这些表达式中的任何一个都是未定义行为(UB)吗?
0 << 32
0LL << 64
如果答案包含对 C 标准的引用,我将不胜感激。
11
最佳答案
1
请参阅,6.5.7按位移位运算符,第 3 段:
对每个操作数执行整数提升。结果的类型是提升后的左操作数的类型。如果右操作数的值为负数或大于或等于提升后的左操作数的宽度,则行为未定义。
假设32位int
和64位的通用配置long long
:
分析0 << 32
表达式:右操作数为整型常量 32,其值等于左操作数的宽度(int)。因此行为未定义。
分析0LL << 64
表达式:右操作数是整型常量 64,其值也等于左操作数的宽度(long long)。因此行为也是未定义的。
和0 << 32
都会0LL << 64
导致 C 中的未定义行为 (UB)。
10
-
1@Shelton Liu 您能修改一下您的答案吗?
– -
1这个答案既完全正确又完全错误:这些表达式确实有未定义的行为,但仅仅是因为这个答案引用的段落之前的段落。
– -
1@lollol 编辑后答案现在正确了。在这种情况下,左操作数的值无关紧要,因为右操作数导致了 UB。无论左移还是右移,它都是 UB。
– -
1删除了我之前的评论。他们参考了编辑前的原始答案。
–
-
4此答案假设一台机器具有 32 位
int
对象和 64 位对象。在具有较小和对象long long
的机器上,它也是 UB (出于同样的原因)。在具有较大类型的机器上,它不是 UB,但我怀疑是否存在这样的机器。int
long long
–
|
–
0 << (CHAR_BIT * sizeof 0)
和吗0LL << (CHAR_BIT * sizeof 0LL)
?–
–
–
–
|