Joe Pineda Joe Pineda - 10 months ago 62
C Question

Is short-circuiting boolean operators mandated in C/C++? And evaluation order?

Does the ANSI standard mandate logic operators to be short-circuited, in either C or C++?

I'm confused for I recall the K&R book saying your code shouldn't depend on these operations being short circuited, for they may not. Could someone please point out where in the standard it's said logic ops are always short-circuited? I'm mostly interested on C++, an answer also for C would be great.

I also remember reading (can't remember where) that evaluation order isn't strictly defined, so your code shouldn't depend or assume functions within an expression would be executed in a specific order: by the end of a statement all referenced functions will have been called, but the compiler has freedom in selecting the most efficient order.

Does the standard indicate the evaluation order of this expression?

if( functionA() && functionB() && functionC() ) cout<<"Hello world";

Answer Source

Yes, short-circuiting and evaluation order are required for operators || and && in both C and C++ standards.

C++ standard says (there should be an equivalent clause in the C standard):


In the evaluation of the following expressions

a && b
a || b
a ? b : c
a , b

using the built-in meaning of the operators in these expressions, there is a sequence point after the evaluation of the first expression (12).

In C++ there is an extra trap: short-circuiting does NOT apply to types that overload operators || and &&.

Footnote 12: The operators indicated in this paragraph are the built-in operators, as described in clause 5. When one of these operators is overloaded (clause 13) in a valid context, thus designating a user-defined operator function, the expression designates a function invocation, and the operands form an argument list, without an implied sequence point between them.

It is usually not recommended to overload these operators in C++ unless you have a very specific requirement. You can do it, but it may break expected behaviour in other people's code, especially if these operators are used indirectly via instantiating templates with the type overloading these operators.