为什么"int >> 32"并不总是零?

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

本文关键字:gt int 为什么      更新时间:2023-10-16

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

例如,该代码在gcc 4.8.3:中给出了带有-O0的45和带有-O3的0选项

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

为什么会是这样?

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

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

至于特定的未定义行为,我认为如下所示:

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

您可以检查程序集输出,看看我的预测是否正确。