理解C ++ 14

时间:2016-01-31 04:38:47

标签: c++ bit-manipulation language-lawyer c++14 bit-shift

根据cppreference

  

对于已签名的aa << b的值为a * 2^b(如果是)   可表示[在(从C ++ 14开始)的无符号版本]返回   type [(然后转换为signed:这使得它合法   创建INT_MIN1 << 31)(因为C ++ 14)],否则就是行为   未定义。

我不太明白这个规范。如果在返回类型的无符号版本中可表示,那么它究竟意味着什么?它是否仅适用于签名值为非负值的情况? INT_MIN << 1-1 << 31定义明确吗?

1 个答案:

答案 0 :(得分:1)

如果我们转到C ++ 14标准源代码,这就是我们发现的内容(突出显示有关无符号类型的部分):

  

E1 << E2的值为E1左移E2位位置;空位是零填充的。如果E1具有无符号类型,则结果的值为E1 × 2 E2 ,比结果类型中可表示的最大值减少一个模数。否则,如果E1具有签名类型和非负值,则E1 × 2 E2 可在结果类型的相应无符号类型中表示,然后转换为结果类型的值是结果值;否则,行为未定义。

对于std::numeric_limits<int>::digits为31的平台,执行1 << 31是合法的。 unsigned int中的结果值为0x800000002147483648。但是,对于这样的平台,该数字超出了int的有效值范围。但是,当被视为双补码表示int时,该位模式等于-2147483648,这与此类平台的INT_MIN相同。

如果您使用

int a = 2 << 31;

您调用未定义的行为,因为2 * 2 31 在该平台中无法表示为unsigned int

  

是INT_MIN&lt;&lt; 1和-1&lt;&lt; 31定义明确?

不,他们不是。按位左移位负数是未定义的行为。请注意在上面突出显示的文本中使用非负值