C++17中数字字面量右移的符号性问题:断言是否可能失败?
数字字面量的右移行为与符号性关联分析
问题描述
我想了解数字字面量的右移行为与其符号性的关联。已知有符号整数变量的右移行为可能因编译器不同而存在差异,那这种情况是否也适用于字面量?
用代码表述疑问会更清晰:
// edited the question's values from 0x80000000 to this to avoid an integer promotion uint32_t x = 0x7F000000 >> 4; uint32_t y = 0x7F000000u >> 4; uint32_t z = 0x7F000000u >> 4u; assert(x == y && y == z);
请问在符合C++17标准的编译器下,这段代码的断言是否有可能失败?
解答
核心规则依据(C++17标准)
整数字面量的类型判定
- 不带后缀的十六进制字面量
0x7F000000:会匹配能容纳它的最小有符号整数类型。在32位或64位int环境中,该值均小于INT_MAX(2147483647),因此类型为int。 - 带
u后缀的0x7F000000u:属于无符号整数字面量,类型为unsigned int(或更大的无符号类型,只要能容纳值)。 4u:无符号字面量,类型为unsigned int。
- 不带后缀的十六进制字面量
右移操作的行为规定
- 有符号整数右移:仅当值为负数时,右移行为是实现定义的(算术/逻辑右移均可);若值为非负,标准强制要求执行逻辑右移(高位补0)。
- 无符号整数右移:无论值是什么,标准强制要求执行逻辑右移,高位始终补0,无实现差异。
代码逐一分析
0x7F000000 >> 4:0x7F000000是非负有符号int,右移4位执行逻辑右移,结果为0x07F00000,赋值给uint32_t x时类型转换不改变数值。0x7F000000u >> 4:无符号字面量右移4位,逻辑右移结果为0x07F00000,赋值给uint32_t y数值不变。0x7F000000u >> 4u:两个操作数均为无符号类型,右移执行逻辑右移,结果仍为0x07F00000,赋值给uint32_t z数值不变。
综上,x、y、z的数值完全一致,在符合C++17标准的编译器下,断言不可能失败。
内容的提问来源于stack exchange,提问作者Anne Quinn
相关产品推荐
相关产品推荐

