C ++:是否定义了负值和大值的左/右位移?

时间:2011-09-25 08:17:36

标签: c++ bit-manipulation

我的问题是,在C ++中,是否定义了以下代码?一些吗?如果是的话,它应该在这四种场景中做什么?

word <<  100;
word >>  100;
word << -100;
word >> -100;

字是uint32_t

(这是3D照明渲染器的一个瓶颈。我想做的最内层循环中的一个较小的改进是消除不必要的条件分叉。其中一个分叉是检查左移是否应该完成作为汉明重量计数的一部分,在几个32位字上。如果左移接受荒谬值,则根本不需要进行检查。

2 个答案:

答案 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