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

Den*_*rin 3 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);
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

小智 22

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

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

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

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

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