c++ - 被未定义的 C++ 移位运算符行为和包装混淆 "pattern space"

标签 c++ undefined-behavior bit-shift

我对我在 article on undefined C++ behavior 的 Shift Operators 部分读到的内容感到困惑.

On the ARM architecture, the shift operators always behave as if they take place in a 256-bit pattern space, regardless of the operand size--that is, the pattern repeats, or "wraps around", only every 256 positions. Another way of thinking of this is that the pattern is shifted the specified number of positions modulo 256. Then, of course, the result contains just the least-significant bits of the pattern space.

表格特别奇怪:

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     |
+-----------------------------------+

这些价​​值观是什么,它们为何重要?

shift operators不要包裹。 根据 C++ 规范,如果将 32 位值左移 32,结果始终为 0。 (编辑:我错了,请查看答案!)那么这篇文章的目的是什么?什么是未定义的行为?

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

printf("%d", 1 << 32);

应该是this code snippet说明问题:

// 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;
}

我希望返回值是 lo,因为程序员移走了所有 hi 位。警告很好,因为这可能是一个错误,但我没有看到任何未定义的行为......

最佳答案

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

这就是它未定义的原因。

在您使用文字的示例中 1 << 32 ,很可能是编译器计算的值,这就是为什么它是 0 .在真正的 x86 硬件上尝试操作,你会得到 1 .

关于c++ - 被未定义的 C++ 移位运算符行为和包装混淆 "pattern space",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13087816/

相关文章:

c++ - 为什么程序调用 strncat() 会产生段错误?

c++ - 有和没有骨架的网格应该使用不同的着色器吗?

c++ - 如何在 OpenCv 中轻松检测 2 个 ROI 是否相交?

c++ - 转换 View 的 std::prev 上的未定义行为

javascript - 语言如何处理复合运算符的副作用?

c++ - shift -1 到 sizeof(int) 在 C++ 中生成两个不同的结果

c++ - 如何制作仅屏蔽 32 位的某些部分(索引)的位掩码?

c++ - 分析 OpenMP 并行化 C++ 代码

c++ - 用逗号相互依赖初始化?

cpu - 如何在硬件层面上实现转变?