我的问题是,在C ++中,是否定义了以下代码?一些吗?如果是的话,它应该在这四种场景中做什么?
word << 100;
word >> 100;
word << -100;
word >> -100;
字是uint32_t
(这是3D照明渲染器的一个瓶颈。我想做的最内层循环中的一个较小的改进是消除不必要的条件分叉。其中一个分叉是检查左移是否应该完成作为汉明重量计数的一部分,在几个32位字上。如果左移接受荒谬值,则根本不需要进行检查。
答案 0 :(得分:10)
在C ++ 0X草案N3290中,§5.8:
如果右操作数为负数,则行为未定义, 或者大于或等于晋升左派的比特长度 操作数。
注意:上面的段落在C ++ 03标准中是相同的。
所以最后两个是未定义的。如果word
长度至少为101位,我认为其他人取决于word
是否已签名。如果word
“小于”101比特,则上述情况适用且行为未定义。
以下是C ++ 0X中该段落的下两部分(这些部分在C ++ 03中有所不同):
E1的值<&lt; E2是E1左移E2位位置;空位是零填充的。如果E1有无符号 类型,结果的值是E1×2E2,减去模数比可表示的最大值多一个 在结果类型中。否则,如果E1具有带符号类型和非负值,则E1×2E2可表示 在结果类型中,那就是结果值;否则,行为未定义。
E1的值&gt;&gt; E2是E1右移E2位位置。如果E1具有无符号类型或E1具有签名 类型和非负值,结果的值是E1 / 2E2的商的整数部分。如果E1 具有签名类型和负值,结果值是实现定义的。
答案 1 :(得分:7)
C标准没有说明当班次计数为负或大于(或甚至等于)变量的精度时会发生什么。
原因是C标准不希望强加一种在参数移位时需要额外代码的行为。由于不同的CPU做不同的事情,标准表明任何事情都可能发生。
使用x86硬件时,移位运算符仅使用移位计数器的最后5位来决定移位量(通过读取CPU reference manual可以看出这一点)所以这是任何C或C ++最可能发生的情况该平台上的编译器。
有关类似问题,另请参阅this answer。