逻辑AND、OR:是否保证从左到右求值? [重复]

问题描述 投票:0回答:1

逻辑运算符 (

&&
||
) 的从左到右求值是否有保证?

假设我有这个:

SDL_Event event;

if (SDL_PollEvent(&event)) {
    if (event.type == SDL_QUIT) {
            // do stuff
    }
}

这保证和这个一样吗?

SDL_Event event;

if (SDL_PollEvent(&event) && event.type == SDL_QUIT) {
    // do stuff
}

这也可能非常重要,假设我们有两个要求,

a
b
。要求
a
b
更有可能失败。那么说
if (a && b)
比说
if (b && a)
更有效率。

c++ logical-operators operator-precedence short-circuiting
1个回答
50
投票

是的,这是有保证的,否则这样的运算符将失去很多用处。

重要通知:这仅对内置&&

||
有效;如果某些犯罪分子重载它们,它们将被视为“常规”重载二元运算符,因此在这种情况下,
两个操作数都会被始终评估,并且像往常一样以未指定的顺序进行评估。因此,永远不要超载它们 - 它打破了关于程序控制流的一个非常重要的假设。


相关标准报价

内置

&&
||
 保证短路行为

§5.14 ¶1

&

 不同,
&&
 保证从左到右求值:如果第一个操作数是 
false
,则不求值第二个操作数。

§5.15 ¶1

|

不同,
||
保证从左到右评估;此外,如果第一个操作数的计算结果为 
true
,则不会计算第二个操作数。

如果重载,它们的行为就像“常规”二元运算符(没有短路或保证评估顺序)

§13.5 ¶9

第 13.5.3 至 13.5.7 款中未明确提及的运算符充当遵守 13.5.1 或 13.5.2 规则的普通一元和二元运算符。

&&

||
 在这些子条款中没有明确提及,因此常规 §13.5.2 成立:

§13.5.2 ¶1

二元运算符应由具有一个参数的非静态成员函数(9.3)或具有两个参数的非成员函数来实现。因此,对于任何二元运算符

@

x@y
 都可以解释为
  作为 
x.operator@(y)
operator@(x,y)

没有特殊规定仅评估一侧或按特定顺序评估。

(所有引用自 C++11 标准)

© www.soinside.com 2019 - 2024. All rights reserved.