编译器能否优化掉64位到32位整数类型的赋值转换操作?
无符号整数截断的编译器优化规则说明
现有代码如下:
uint64_t truncate(uint64_t num) { uint32_t lessBits = static_cast<uint32_t>(num); return static_cast<uint64_t>(lessBits); }
针对你提出的问题,结论非常明确:你的猜测完全正确,编译器不允许优化掉这里的类型转换操作直接返回完整64位值,必须严格保留32位截断的行为,相关规则依据如下:
- C/C++标准对无符号整数的转换做了明确定义:将一个无符号整数转换为位宽更小的无符号整数类型时,返回结果为原数值对
2^N取模后的值,N是目标类型的位宽。上述代码中将uint64_t转为uint32_t的操作,明确要求丢弃高32位,仅保留低32位存入lessBits变量。 - 编译器的所有优化都必须遵守as-if规则:优化后程序的可观测行为必须和标准定义的未优化程序行为完全一致。如果省略截断操作直接返回原始的64位输入,当输入值的高32位不为0时,输出结果就会和标准规定的结果不符,属于违反标准的非法优化,合规的编译器都不会这么做。
- 你观测到的生成
mov eax, ...指令的结果完全符合预期:x86-64架构下对32位寄存器的写入操作会自动将对应64位寄存器的高32位清零,刚好匹配“先截断为32位、再零扩展为64位”的语义,是该逻辑的高效实现。
内容的提问来源于stack exchange,提问作者Martin Ba
相关产品推荐
相关产品推荐

