与标题状态一样,整数(或任何数字数据类型,如浮点数等)比较运算符(==、!=、>、>=、<、<=)在 C++ 中是否短路?
4 回答
他们不能短路。要知道x == y
,x != y
等是否是,true
或者false
您需要同时评估 x 和 y。短路是指逻辑布尔运算符&&
和||
. 如果第一个参数为假,则逻辑 AND 为假,如果第一个参数为真,则逻辑 OR 为真。在这些情况下,您不需要评估第二个参数,这称为短路。
编辑:这遵循了为什么当操作数是无符号整数并且为零x >= y
时不短路的讨论:x
对于逻辑操作数,短路是免费的,并且是实现中立的。的机器代码if(f() && g()) stmt;
可能类似于以下内容:
call f
test return value of f
jump to next on zero
call g
test return value of g
jump to next on zero
execute stmt
next: ...
为了防止短路,您实际上需要对运算符的结果进行计算并在此之后对其进行测试。这会带你一个寄存器并使代码效率降低。
对于非逻辑运算符,情况正好相反。强制短路意味着:
- 编译器不能选择使用最少寄存器数的表达式的评估。
- 在许多情况下,语义可能是实现定义的(甚至是未定义的),例如与最大值进行比较时。
编译器需要添加额外的测试/跳转。对于
if(f() > g()) stmt;
机器代码将如下所示:call f mov return value of f to R1 test return value of f jump to next on zero call g compare R1 with return value of g jump to next on less-than equal execute stmt next: ...
注意第一次测试和跳转是没有必要的。
否。比较运算符需要两个操作数来评估正确答案。相比之下,逻辑运算符&&
在||
某些情况下不需要评估正确的操作数来获得正确的答案,因此会“短路”。
不,他们怎么可能。为了检查您是否1 == 2
必须同时检查 1 和 2。(Ofcoruse,编译器可以做很多重新排序、静态检查、优化等,但这不是 C++ 继承的)
那将如何运作?短路意味着您可以避免仅根据评估 LHS 的结果来评估 RHS。
例如
true || false
不需要评估 RHS,因为true || x
无论true
结果x
如何。
但这不适用于您列出的任何比较。例如:
5 == x
你怎么能在不知道的情况下知道表达式的结果x
?