Search code examples
c++operator-precedence

C++ Order of Evaluation of Subexpressions with Logical Operators


There are lots of questions on concepts of precedence and order of evaluation but I failed to find one that refers to my special case.

Consider the following statement:

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

Is it guaranteed that f(0) will be evaluated first? Notice that the operator is &&.

My confusion stems from what I've read in "The C++ Programming Language, (Stroustrup, 4ed, 2013)".

In section 10.3.2 of the book, it says:

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

This seems to apply to all operators including && operator, but in a following paragraph it says:

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

There is also another mention of this in section 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.

This last quote implies that && and || evaluate their 1st argument first, so it seems to reinforce my assumption that operators mentioned in 2nd quote are exceptions to 1st quote, but I cannot draw a definitive conclusion from this last example either, as the expression contains only one subexpression as opposed to my example, which contains two.


Solution

  • The special sequencing behavior of &&, ||, and , is well-established in C and C++. The first sentence you quoted should say "The order of evaluation of subexpressions within an expression is generally unspecified" or "With a few specific exceptions, the order of evaluation of subexpressions within an expression is unspecified".

    You asked about C++, but this question in the C FAQ list is pertinent.


    Addendum: I just realized that "unspecified" is a better word in these rules than "undefined". Writing something like f() + g() doesn't give you undefined behavior. You just have no way of knowing whether f or g might be called first.