c++ - 在 x86 机器上移动超过 32 位的 uint64_t 整数未定义行为?

标签 c++ c x86 bit-shift uint64

学习艰难,我尝试在 x86 机器上将 long longuint64_t 左移到 32 位以上,结果 0 .我隐约记得在某处读过比 32 位机器移位运算符仅在前 32 位上工作但无法记忆来源。 我想知道在 x86 机器上移动超过 32 位的 uint64_t 整数是否是未定义行为?

最佳答案

标准说(n1570 中的 6.5.7):

3 The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2 , reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

5 The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2 . If E1 has a signed type and a negative value, the resulting value is implementation-defined.

转移 uint64_t小于 64 位的距离完全由标准定义。

自从 long long必须至少为 64 位,移位 long long如果结果不溢出,则小于 64 位的值由非负值标准定义。

但是,请注意,如果您编写适合 32 位的文字,例如uint64_t s = 1 << 32正如@drhirsch 所推测的那样,您实际上并没有移动 64 位值,而是移动 32 位值。那是未定义的行为。

最常见的结果是偏移 shift_distance % 32或 0,取决于硬件的功能(并假设编译器的编译时评估模拟硬件语义,而不是鼻恶魔。)

使用1ULL < 63 使移位操作数 unsigned long long 在转变之前

关于c++ - 在 x86 机器上移动超过 32 位的 uint64_t 整数未定义行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10499104/

相关文章:

c - 在 C 中将 ","分隔列表拆分为数组的最佳方法是什么?

c - ubuntu 和 libcap(功能)未定义引用

c - 当初始化固定大小的 char 数组时没有足够的空间容纳 null 终止符时,不会出现编译器错误

x86 - 使用SSE计算绝对值的最快方法

c - 基于汇编32位(x86)编写C代码

c++ - 如何在gentoo上编译Mellanox libvma?

c++ - hh :mm format from a line 中的读取时间

javascript - 这个 milw0rm 堆喷射漏洞是如何工作的?

c++ - 使用 boost::spirit 在 C++ 中读取二维数组

c++ - g++4.9 不支持 std::align