C++ 被未定义的C+所迷惑+;轮班操作员行为和包装;“模式空间”;

C++ 被未定义的C+所迷惑+;轮班操作员行为和包装;“模式空间”;,c++,undefined-behavior,bit-shift,C++,Undefined Behavior,Bit Shift,我被我在一篇文章的轮班操作员部分读到的东西弄糊涂了 在ARM体系结构上,移位运算符的行为总是如同它们发生在256位模式空间中一样,而与操作数大小无关——也就是说,模式仅每隔256个位置重复或“环绕”。另一种思路是将模式移位到256模的指定位置数。当然,结果只包含模式空间中最低有效位 这些桌子特别奇怪: Given a 32-bit integer with a value of 1: +-----------------------------------+ | Shift left AR

我被我在一篇文章的轮班操作员部分读到的东西弄糊涂了

在ARM体系结构上,移位运算符的行为总是如同它们发生在256位模式空间中一样,而与操作数大小无关——也就是说,模式仅每隔256个位置重复或“环绕”。另一种思路是将模式移位到256模的指定位置数。当然,结果只包含模式空间中最低有效位

这些桌子特别奇怪:

Given a 32-bit integer with a value of 1:
+-----------------------------------+
| Shift left    ARM    x86    x64   |
+-----------------------------------+
| 32            0      1      1     |
| 48            0      32768  32768 |
| 64            0      1      1     |
+-----------------------------------+
这些价值观是什么?它们为什么重要

这件衣服不包。根据C++规范,如果将32位的值移32,结果总是0。(编辑:我错了,请看答案!)那么这篇文章的意思是什么?什么是未定义的行为

在x86上运行此代码时,我得到
0

printf("%d", 1 << 32);
printf(“%d”),1
结果的类型是提升后的左操作数的类型。如果右操作数为负,或大于或等于提升后的左操作数的位长度,则行为未定义


这来自C++11中的§5.8/1。如果整数为32位,则不能按32移位(右移位或左移位,无论左操作数是否有符号).

如果使用x86或x64机器指令移位值,它们将屏蔽移位量,并仅使用低位进行实际移位。其他一些硬件可能不会这样做

这就是为什么它没有定义

在您的示例中,文字
1

根据C++规范,如果将32位的值移32,则结果始终为0</p> 不,这不是标准所说的。将32位类型移位32位或更多(5.8/1)是未定义的行为


由于ARM上的256位移位(没有257位或更大的类型)是未定义的行为,CPU完全有权在该点进行换位。

谢谢,错过了这一部分!我只读了“E1的值”
// C4293.cpp
// compile with: /c /W1
unsigned __int64 combine (unsigned lo, unsigned hi) {

    return (hi << 32) | lo;   // C4293

    // try the following line instead
    // return ( (unsigned __int64)hi << 32) | lo;
}