在C中按位运算后的类型转换警告 [英] Type conversion warning after bitwise operations in C

查看:91
本文介绍了在C中按位运算后的类型转换警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您如何解释第7行会收到警告,但不会收到第5行或第6行的警告?

How do you explain that line 7 gets a warning, but not line 5 or line 6?

int main()
{
    unsigned char a = 0xFF;
    unsigned char b = 0xFF;
    a = a | b;                        // 5: (no warning)
    a = (unsigned char)(b & 0xF);     // 6: (no warning)
    a = a | (unsigned char)(b & 0xF); // 7: (warning)
    return 0;
}

在32位体系结构(Windows PC)上编译时的GCC 4.6.2输出:

GCC 4.6.2 output when compiled on 32-bit architecture (Windows PC):

gcc -c main.c --std=c89 -Wall -Wextra -Wconversion -pedantic
main.c: In function 'main':
main.c:7:11: warning: conversion to 'unsigned char' from 'int' may alter its value [-Wconversion]

如果这可以帮助您理解我的问题,这是我的看法(可能不正确!):

If this helps you understand my question, here is how I see this (probably incorrect!):

我想在32位计算机上对32位数字进行操作.由于unsigned char适合32位int,因此运算结果为32位int.但是由于GCC在第5行和第6行没有给出警告,所以我想还有其他事情发生:

I suppose that on a 32-bit machine operations are done on 32-bit numbers. Since unsigned char fits into 32-bit int, the operation result is 32-bit int. But since GCC doesn't give warnings on lines 5 and 6, I guess there is something else going on:

第5行: GCC认为(uchar)或(uchar)永远不会大于MAX(uchar),因此没有警告.

line 5: GCC figures that (uchar) OR (uchar) is never bigger than MAX(uchar), so no warning.

第6行: GCC认为(uchar)AND 0xF永远不会大于MAX(uchar),因此没有警告.甚至没有必要进行强制转换.

line 6: GCC figures that (uchar) AND 0xF is never bigger than MAX(uchar), so no warning. Explicit cast is not even necessary.

第7行:基于上述假设:AND不应发出警告(自第6行起),或也不应该发出警告(自第5行起).

line 7: Based on assumptions above: AND should not give warning (since line 6), OR should not give warning either (since line 5).

我猜我那里的逻辑有问题.帮助我了解编译器的逻辑.

I guess my logic is faulty somewhere there. Help me understand the logic of the compiler.

推荐答案

编译器是人为构建的,他们没有无限的时间来找出所有可以决定的算术可能性,哪些情况值得发出警告.

Compilers are built by people and they don't have infinite time to figure out all arithmetic possibilities to decide, which cases are worth issuing a warning.

因此,我(注意)认为编译器工程师会采取以下方式:

So I believe (attention opinion) that compiler engineers would go the following way:

  • 如果代码看起来好像是错误的,通常会发出警告.
  • 找到所有可以纠正编译器以使其易于工作的明显情况.
  • 将其余警告保留为误报,因为此人要么知道自己在做什么,要么会放心编译器正在警告.

我希望人们在编写代码时将结果强制转换为(unsigned char)或最外面的运算符使用常量屏蔽所有更高字节的代码.

I would expect people to write code where either the result is casted to (unsigned char) or where the outermost operator masks all higher bytes with a constant.

    这样
  • a = (unsigned char) ( /* some obscure bit-wise expressoin */ );就可以了
  • a = 0xff & ( /* some obscure bit-wise expressoin */ );也可以
  • a = (unsigned char) ( /* some obscure bit-wise expressoin */ ); would be OK then
  • a = 0xff & ( /* some obscure bit-wise expressoin */ ); also OK

如果您知道编译器正确地转换了这两种模式,那么其他情况就不会太麻烦您了.

if you know that your compiler translates those two patterns correctly the other cases shouldn't bother you too much.

我已经看到编译器由于a = a | b;而发出警告,因此GCC不发出警告是免费的. gcc可能只是推断a | b中的常量分配,因此将其替换为0xff | 0xff,众所周知,该函数可以正常工作.如果发生这种情况,尽管我不知道为什么它不能在其他语句中得出a的常量值.

I've seen compilers that would issue a warning because of a = a | b; so GCC not giving a warning is a free bonus. it might be, that gcc just infers the constant assignment in a | b and therefore replaces it with 0xff | 0xff which is known to work without problems. If that happens though I don't know why it cannot derive the constant value of a in the other statements.

这篇关于在C中按位运算后的类型转换警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆