C++中右移的未定义行为

R2B*_*2B2 14 c++ bit-shift

来自cppreference.com:

对于无符号a和带有非负值的带符号a,a >> b的值是a/b的整数部分.对于负数a,a >> b的值是实现定义的(在大多数实现中,它执行算术右移,因此结果保持为负).

在任何情况下,如果右操作数的值为负或大于或等于提升的左操作数中的位数,则行为未定义.

如果右操作数大于或等于提升左操作数中的位数,为什么我们有一个未定义的行为?
在我看来,结果应为0(至少对于无符号/正整数)...

特别是,使用g ++(版本4.8.4,Ubuntu):

unsigned int x = 1;
cout << (x >> 16 >> 16) << " " << (x >> 32) << endl;
Run Code Online (Sandbox Code Playgroud)

得到: 0 1

asc*_*ler 31

C++的目标之一是允许快速,高效的代码,"靠近硬件".在大多数硬件上,单个操作码可以实现整数右移或左移.问题是,在这种情况下,不同的CPU具有不同的行为,其中移位幅度大于比特数.

因此,如果C++强制要求移位操作的特定行为,那么当为操作码行为与所有标准要求不匹配的CPU生成代码时,编译器需要插入检查和逻辑以确保结果符合标准的定义案例.除非优化器能够证明角落情况不会真正发生,否则几乎所有内置移位运算符的使用都需要这种情况.增加的检查和逻辑可能会减慢程序的速度.

  • 这并不能解释为什么它不是实现定义的行为,而是完全未定义的行为.这也将允许"接近硬件"实现. (6认同)