"IF" argument evaluation order?
Solution 1
The evaluation order is specified by the standard and is left-to-right
. The left-most expression will always be evaluated first with the &&
clause.
If you want b
to be evaluated first:
if(b && a)
{
//do something
}
If both arguments are methods and you want both of them to be evaluated regardless of their result:
bool rb = b();
bool ra = a();
if ( ra && rb )
{
//do something
}
Solution 2
With C++ there are only a few operators that guarantee the evaluation order
-
operator &&
evaluates left operand first and if the value is logicallyfalse
then it avoids evaluating the right operand. Typical use is for exampleif (x > 0 && k/x < limit) ...
that avoids division by zero problems. -
operator ||
evaluates left operand first and if the value is logicallytrue
then it avoids evaluating the right operand. For exampleif (overwrite_files || confirm("File existing, overwrite?")) ...
will not ask confirmation when the flagoverwrite_files
is set. -
operator ,
evaluates left operand first and then right operand anyway, returning the value of right operand. This operator is not used very often. Note that commas between parameters in a function call are not comma operators and the order of evaluation is not guaranteed. -
The ternary operator
x?y:z
evaluatesx
first, and then depending on the logical value of the result evaluates either onlyy
or onlyz
.
For all other operators the order of evaluation is not specified.
The situation is actually worse because it's not that the order is not specified, but that there is not even an "order" for the expression at all, and for example in
std::cout << f() << g() << x(k(), h());
it's possible that functions will be called in the order h-g-k-x-f
(this is a bit disturbing because the mental model of <<
operator conveys somehow the idea of sequentiality but in reality respects the sequence only in the order results are put on the stream and not in the order the results are computed).
Obviously the value dependencies in the expression may introduce some order guarantee; for example in the above expression it's guaranteed that both k()
and h()
will be called before x(...)
because the return values from both are needed to call x
(C++ is not lazy).
Note also that the guarantees for &&
, ||
and ,
are valid only for predefined operators. If you overload those operators for your types they will be in that case like normal function calls and the order of evaluation of the operands will be unspecified.
Changes since C++17
C++17 introduced some extra ad-hoc specific guarantees about evaluation order (for example in the left-shift operator <<
). For all the details see https://stackoverflow.com/a/38501596/320726
Solution 3
In this case, since you're using &&
, a
will always be evaluated first because the result is used to determine whether or not to short-circuit the expression.
If a
returns false, then b
is not allowed to evaluate at all.
Solution 4
Every value computation and side effect of the first (left) argument of the built-in logical AND operator && and the built-in logical OR operator || is sequenced before every value computation and side effect of the second (right) argument.
Read here for a more exhaustive explanation of the rules set: order evaluation
Solution 5
The built-in &&
operator always evaluates its left operand first. For example:
if (a && b)
{
//block of code
}
If a
is false
, then b
will not be evaluated.
If you want b
to be evaluated first, and a
only if b
is true, simply write the expression the other way around:
if (b && a)
{
//block of code
}
Related videos on Youtube
winnerrrr
Updated on July 09, 2022Comments
-
winnerrrr almost 2 years
if(a && b) { do something; }
is there any possibility to evaluate arguments from right to left(b -> a)?
if "yes", what influences the evaluation order?
(i'm using VS2008)
-
Prince John Wesley over 12 years
if( b && a )
will do it for you. -
CloudyMarble over 12 yearstry if(b && a). try this link: msdn.microsoft.com/en-us/library/2bxt6kc4.aspx
-
-
Jonathan Leffler over 12 yearsThe question is about C++, not C# (though you're probably correct that both do the same thing, inspired by what C does).
-
Dylan Smith over 12 yearsoops! I assume they're both the same tho as you say.
-
dalle over 12 years... unless
operator&&
is overloaded. Which is possible, but regarded as bad design. -
James Kanze over 12 yearsJust a nit, but value dependencies also impose an order. In an expression like
(a + b) * c
,a
andb
must be evaluated before the addition, and the addition must occur before the multiplication. Generally, this effect is unobservable, but if the operators are overloaded, it may be visible. -
6502 over 12 years@JamesKanze: Ok. I think it's sort of obvious for a language like C++, but added anyway a note for that.
-
Aviad Rozenhek about 11 yearsthat's a relief ... for once c++ has the correct default behavior instead of a surprisingly obscure one
-
6502 about 10 years@AviadRozenhek: you're right to be scared because indeed it's possible that expression
b
is evaluated before expressiona
. For this to happen however the operator must not be the predefined&&
logical-and operator, but an overload for user-defined types. In that case the order of evaluation of the arguments is unspecified (and worse than that you can't even expect an actual ordering because evaluation can even be "intermixed": a bit ofa
, then some ofb
, then more ofa
, then again some remaining bits ofb
and finally the custom operator is called). -
mdw7326 over 9 yearsWhat's the case if
||
is used instead? It should remain the same unless some compiler optimizations gunk it iu, correct @6502? -
Luchian Grigore over 9 years@mdw7326 || is also short-circuiting - if the first condition is true, the second one won't get evaluated. It's not a compiler optimization, it's required by the standard.
-
mdw7326 over 9 years@LuchianGrigore I understand that, I guess I didn't word my question carefully enough. With the
||
operator, the expressions are evaluated in order (left-to-right) until all expressions are evaluated or until an expression is found to be true, correct? -
6502 over 9 years@mdw7326: If you check my answer you will see a detailed description of the only operators that guarantee an evaluation order in C++, with examples of common use of short circuiting for
&&
and||
. -
ruhig brauner almost 8 yearsI am most certain that the following is the case but is it safe to do something like this then:
Obj * obj; if(obj && obj->foo()) {...}
I assume that it checks wheter obj is not NULL and only if it's not NULL, it will check the result ofobj->foo()
, right?