三元运算符内强制转换导致下溢问题咨询
C++三元运算符与if-else的类型差异问题
代码片段
#include <iostream> int main() { int64_t res; int some_val = 5; if(false) { res = static_cast<uint32_t>(some_val); } else { res = -1; } std::cout << "first check: " << res << std::endl; res = (false) ? static_cast<uint32_t>(some_val) : (-1); std::cout << "second check: " << res << std::endl; return 0; }
程序输出
first check: -1
second check: 4294967295
问题
我原本认为这两段逻辑等价,都应返回-1。查阅文档得知三元运算符会将两个操作数转换为公共类型,我预期会选择int64_t(可同时表示两种类型),但实际却选择了uint32_t,导致-1转换时发生下溢。请问这是什么原因?
解答
这是因为C++中三元运算符的类型推导遵循常规算术转换规则,和if-else分支直接赋值的逻辑完全不同:
if-else分支的赋值逻辑:
每个分支的表达式独立计算后直接赋值给res(int64_t类型)。else分支的-1是int类型,赋值时会被隐式转换为int64_t的-1,所以输出正常。三元运算符的类型推导逻辑:
三元运算符需要先确定整个表达式的公共类型,再将两个操作数转换为该类型,最后才赋值给res。
这里两个操作数分别是uint32_t类型的值和int类型的-1,根据常规算术转换规则:- 两者转换等级相同(都是32位整数类型);
- 当无符号类型和同等级的有符号类型相遇时,有符号类型会被转换为无符号类型。
所以-1会被转换为uint32_t类型的4294967295,之后这个值再赋值给int64_t的res,最终输出该数值。
本质区别在于:三元运算符是先统一操作数类型再赋值,if-else是各自赋值时才做类型转换。
内容的提问来源于stack exchange,提问作者someCoder
相关产品推荐
相关产品推荐

