Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"IF" argument evaluation order?

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)

like image 802
winnerrrr Avatar asked Oct 28 '11 05:10

winnerrrr


People also ask

Are IF statements evaluated in order?

The if statements are evaluated in order until one of the if expressions is true or the end of the if/else if chain is reached. If the end of the if/else if chain is reached without a true expression, no code blocks are executed.

Are IF statements evaluated left to right?

It will evaluate from left to right and short-circuit the evaluation if it can (e.g. if a evaluates to false it won't evaluate b). If you care about the order they are evaluated in you just need to specify them in the desired order of evaluation in your if statement.

What is the order of evaluation in the expression?

"Order of evaluation" refers to when different subexpressions within the same expression are evaulated relative to each other. you have the usual precedence rules between multiplication and addition.

What is the order of evaluation of the operators?

Only the sequential-evaluation ( , ), logical-AND ( && ), logical-OR ( || ), conditional-expression ( ? : ), and function-call operators constitute sequence points, and therefore guarantee a particular order of evaluation for their operands.


2 Answers

With C++ there are only a few operators that guarantee the evaluation order

  • operator && evaluates left operand first and if the value is logically false then it avoids evaluating the right operand. Typical use is for example if (x > 0 && k/x < limit) ... that avoids division by zero problems.

  • operator || evaluates left operand first and if the value is logically true then it avoids evaluating the right operand. For example if (overwrite_files || confirm("File existing, overwrite?")) ... will not ask confirmation when the flag overwrite_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 evaluates x first, and then depending on the logical value of the result evaluates either only y or only z.

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

like image 130
6502 Avatar answered Sep 20 '22 06:09

6502


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 } 
like image 28
Luchian Grigore Avatar answered Sep 20 '22 06:09

Luchian Grigore