带逻辑运算符的子表达式的 C++ 求值顺序

C++ Order of Evaluation of Subexpressions with Logical Operators

有很多关于 precedenceorder of evaluation 概念的问题,但我没有找到适合我的特殊情况的问题.

考虑以下语句:

if(f(0) && g(0)) {};

是否保证首先计算 f(0)?请注意运算符是 &&.

我的困惑源于我在“The C++ Programming Language, (Stroustrup, 4ed, 2013)”中读到的内容。

书中10.3.2节说:

The order of evaluation of subexpressions within an expression is undefined. In particular, you cannot assume that the expression is evaluated left-to-right. For example:

int x = f(2)+g(3); // undefined whether f() or g() is called first

这似乎适用于所有运算符 包括 && 运算符,但在下面的段落中它说:

The operators , (comma), && (logical and), and || (logical or) guarantee that their left-hand operand is evaluated before their right-hand operand.

11.1.1 节中也提到了这一点:

The && and || operators evaluate their second argument only if necessary, so they can be used to control evaluation order (§10.3.2). For example:

while (p && !whitespace(p)) ++p;

Here, p is not dereferenced if it is the nullptr.

这最后一句话暗示 && 和 ||首先评估他们的第一个参数,因此它似乎强化了我的假设,即第二个引用中提到的运算符是第一个引用的例外,但我也无法从最后一个示例中得出明确的结论,因为表达式仅包含 one 子表达式与我的示例相反,它包含 two.

&&||, 的特殊排序行为在 C 和 C++ 中得到了很好的确立。你引用的第一句话应该说 "The order of evaluation of subexpressions within an expression is generally unspecified" 或 "With a few specific exceptions, the order of evaluation of subexpressions within an expression is unspecified".

你问的是 C++,但 this question in the C FAQ list 是相关的。


附录:我刚刚意识到 "unspecified" 在这些规则中是一个比 "undefined" 更好的词。写类似 f() + g() 的东西不会给你未定义的行为。您只是无法知道 f 还是 g 可能首先被调用。

是的,保证f(0)先完整求值

这是为了支持称为 短路 的行为,如果第一个 returns false.