在GCC下,以下代码始终返回<<if 的左操作数num1s == 0:
0xFFFFFFFFu << (32-num1s);
Run Code Online (Sandbox Code Playgroud)
读完之后,为什么使用32次以上的整数时,32位整数为何不左移“ <<”?,以及David Heffernan引用的标准,似乎如果左操作数是unsigned,则它是定义的操作。仅当E1(左操作数)具有带符号的类型和非负值时,它才可能导致未定义的行为。
谁能解释标准是否明确指出,如果移位的数量大于该类型包含的位数,则它是未定义的行为?
CoryKramer 已经回答了为什么它是标准未定义的行为。
我将尝试解释它在真实情况下是如何工作的。C++ 编译器通常将32 位整数的<<and>>运算符实现为汇编指令,而不检查操作数范围。这意味着结果取决于移位指令的处理器特定实现。
例如,Intel 处理器的 32 位 SHL/SHR/SAL/SAL 指令规范表示:
目标操作数可以是寄存器或内存位置。计数操作数可以是立即数或寄存器CL。计数被屏蔽为 5 位,这将计数范围限制为 0 到 31。
这意味着这a << b将出现a << (b & 0x1f)在英特尔处理器上。所以移位32位就意味着不移位。
但您不应该依赖此信息!编译器还可以优化代码并使用向量指令实现移位运算符。在这种情况下,即使处理器规范也未指定该行为。
§5.8移位运算符
结果的类型是提升后的左操作数的类型。如果右操作数为负或大于或等于提升后的左操作数的位长度,则该行为是不确定的。
的值
E1 << E2是E1左移位的E2位置;空出的位为零。如果E1具有无符号类型,则结果的值E1 × 2E2将为,比结果类型中可表示的最大值减少模。否则,如果E1具有带符号的类型和非负值,并且E1×2E2可以在结果类型中表示,则为结果值;否则,为结果。否则,行为是不确定的。
| 归档时间: |
|
| 查看次数: |
797 次 |
| 最近记录: |