有人可以解释一下为什么在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);
为什么会这样?
答案 0 :(得分:22)
因为它是未定义的行为:[expr.shift]
说
如果右操作数为负数,或者大于或等于提升左操作数的位长度,则行为未定义。
至于特定未定义的行为,我想它如下:
-O0
,它编译为实际在机器代码中执行右移,并且在某些机器上(例如我相信x86就是这样),移位功能仅在移位时查看移位量的低5位一个32位的字;移位32与移位0相同。-O3
,编译器自己计算常量,只需将0
放入程序中,而不是让它进行计算。您可以检查装配输出以查看我的预测是否正确。