为什么`int>> 32`不总是零?

时间:2015-07-04 04:56:54

标签: c++ c bit-manipulation shift

有人可以解释一下为什么在C / C ++中,一些4字节整数的32位按位移位可能不会返回零吗?为什么它依赖于编译器的-O选项?

例如,此代码在gcc 4.8.3中为45提供-O0和0提供-O3选项:

unsigned int x = 45; // 4 bytes
x = x >> 32;
printf("%u\n", x);

为什么会这样?

1 个答案:

答案 0 :(得分:22)

因为它是未定义的行为:[expr.shift]

  

如果右操作数为负数,或者大于或等于提升左操作数的位长度,则行为未定义。

至于特定未定义的行为,我想它如下:

  • 使用-O0,它编译为实际在机器代码中执行右移,并且在某些机器上(例如我相信x86就是这样),移位功能仅在移位时查看移位量的低5位一个32位的字;移位32与移位0相同。
  • 使用-O3,编译器自己计算常量,只需将0放入程序中,而不是让它进行计算。

您可以检查装配输出以查看我的预测是否正确。