使用运算符<< = on unsigned char时的-wconversion警告

Cad*_*hon 9 c++ gcc bitwise-operators unsigned-char

当我用gcc编译以下代码时:

int main()
{
  unsigned char c = 1;
  c <<= 1;  // WARNING ON THIS LINE
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我收到这个警告:

conversion to ‘unsigned char’ from ‘int’ may alter its value [-Wconversion]

为什么?这段代码有什么问题?实际上,我真的可以在变量<<=上使用oprator unsigned char吗?

编译命令:

g++ test.cpp -Wconversion -o test.exe

Sha*_*our 8

这是一个有效的警告:

c <<= 1;
Run Code Online (Sandbox Code Playgroud)

相当于:

c = c << 1
Run Code Online (Sandbox Code Playgroud)

以及<<说操作数被提升的规则,在这种情况下将被提升为,int并且结果是提升类型.所以会出现从一个转换intunsigned char在其端部可能导致改变的值.

代码有效,警告告诉您正在进行隐式转换,在某些情况下转换可能会改变该值.使用演员表会使警告静音.隐式转换的结果可能非常违反直觉,并且在某些情况下可能是未定义的行为.有关详细信息,请参阅gcc Wconversion wiki.

我没有看到一种方法来删除警告而不用手动扩展操作并使用static_cast:

c = static_cast<unsigned char>( c << 1 );
Run Code Online (Sandbox Code Playgroud)

正如我们从这个gcc bug报告的长线程中看到的那样,并不是每个人都认为这是这个警告的有用案例.

C++标准草案部分参考5.8Shift运算符:

操作数应为整数或无范围的枚举类型,并执行整体促销.结果的类型是提升左操作数的类型[...]

从部分5.17分配和复合赋值运算符:

形式E1 op = E2的表达式的行为等同于E1 = E1 op E2,除了E1仅被评估一次.[...]

  • 请参阅[为什么必须在C和C++中的算术运算之前将short转换为int?](http://stackoverflow.com/q/2437186​​8/1708801)以获取有关为什么操作数被提升为更宽类型的基本原理.主要是因为它导致生成的代码更快. (4认同)