Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 884
Kemal Avatar asked Jun 28 '15 15:06

Kemal


2 Answers

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.

like image 102
Steve Summit Avatar answered Sep 30 '22 02:09

Steve Summit


Yes, it is guaranteed that f(0) will be completely evaluated first.

This is to support behaviour known as short-circuiting, by which we don't need to call the second function at all if the first returns false.

like image 29
TartanLlama Avatar answered Sep 30 '22 01:09

TartanLlama