左移操作员的奇怪整体促销

los*_*yzd 1 c c++ type-conversion

请参阅下面的代码,为什么没有文字"1"的整体推广?

long long n = 50;
long long a = 1 << n; // 262144
long long b = 1LL << n; // 1125899906842624
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 10

按照elazar的要求:

显示的结果是可接受的结果,因为shift调用未定义的行为. 这是因为普通1是一个int,并且移动int范围之外的值0..(sizeof(int) * CHAR_BIT)-1(通常情况下0..31)会导致未定义的行为.

请注意,移位的类型仅受(提升的)左操作数的类型的影响.这是(如同克里斯一次提到的)与大多数其他二元运算符不同,例如加法,其中两个操作数的类型都会影响结果的类型.当然,赋值的类型由左操作数的类型控制,如果需要,右边的值被强制转换为正确的类型(但是赋值的右边的值是在不参考它的类型的情况下计算的)将分配给,如本例所示).

ISO/IEC 9899:2011(C)

§6.5.7按位移位运算符

3对每个操作数执行整数提升.结果的类型是提升的左操作数的类型.如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义.

ISO/IEC 14822:2011(C++)

§5.8转移运营商

操作数应为整数或无范围的枚举类型,并执行整体促销.结果的类型是提升的左操作数的类型.

  • 厄运!您只需花费 10 美元就可以得到一份该标准的副本……这可能是一项更好的投资。 (4认同)
  • @lostyzd我认为因为它是一个非对称运算符,右操作数的大小显然无关紧要.只有它的价值. (2认同)
  • 如果移位运算符与操作数转换中的大多数其他运算符不同,那么这个答案会更好.运算符的这个方面引起了最大的混淆或惊讶,并且理解右操作数的类型不影响左操作数的转换是关键. (2认同)