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

Why is `int >> 32` not always zero?

有人能解释一下为什么某些 4 字节整数的右移 32 位可能 return 在 C/C++ 中不为零吗?为什么它取决于编译器的 -O 选项?

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

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

为什么会这样?

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

The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

至于具体的未定义的行为,我想象如下:

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

您可以检查汇编输出,看看我的预测是否正确。