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

Ann*_*inn 2 c++ bit-manipulation

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

word <<  100;
word >>  100;
word << -100;
word >> -100;
Run Code Online (Sandbox Code Playgroud)

这个词是 uint32_t

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

Mat*_*Mat 11

在C++ 0X草案N3290中,§5.8:

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

注意:上面的段落在C++ 03标准中是相同的.

所以最后两个是未定义的.其他,我相信取决于是否word签名,如果word至少101位长.如果word"小于"101比特,则上述情况适用且行为未定义.

以下是C++ 0X中该段落的下两部分(这些部分在C++ 03中有所不同):

E1 << E2的值是E1左移E2位位置; 空位是零填充的.如果E1具有无符号类型,则结果的值为E1×2E2,比结果类型中可表示的最大值减少一个模数.否则,如果E1具有有符号类型和非负值,并且在结果类型中可以表示E1×2E2,那么这就是结果值; 否则,行为未定义.

E1 >> E2的值是E1右移E2位位置.如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1/2E2的商的整数部分.如果E1具有带符号类型和负值,则结果值是实现定义的.

  • 如果`word`的大小小于100位,那么所有四个都是未定义的. (3认同)

650*_*502 7

C标准没有说明当移位计数为负或大于(或甚至等于)变量的精度时应该发生什么.

原因是C标准不希望强加一种行为,在参数移位的情况下需要发出额外的代码.由于不同的CPU做不同的事情,标准说任何事情都可能发生.

对于x86硬件,移位运算符仅使用移位计数器的最后5位来确定移位量(这可以通过阅读CPU参考手册看到),因此这是该平台上任何C或C++编译器最可能发生的情况.

有关类似问题,请参阅此答案.