1

Please consider the following block of C++-code.

call * pCall;   // Make a pointer to private variable call.
pCall = NULL;   // We are sure that it is a null pointer.

aMemberFuntionThatMayChangeTheValueOfpCall();

if (pCall != NULL and pCall->isDelivered() == false){
   doSomething();
}

I would like to execute some lines of code, here represented by doSomething(), if and only if pCall is not a null pointer and pCall->isDelivered() is false.

However, I read that the order of evaluation is unspecified. So theoretically the compiler may evaluate pCall->isDelivered() first, and run into a run time exception. However, in the debugging sessions it seems to evaluate the and-operator left to right. Can someone please shine a light on this? I don't want any failures of the code when it gets into a production environment or when it gets executed on another machine.

Of course it is possible to make it into two nested if-statements, but this makes the source far more unreadable because I need this kind of code multiple times.

Can anyone tell me how to do this evaluation in one if-statement such that there is no misevaluation?

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
martinvb
  • 81
  • 1
  • 9
  • 1
    Where have you read that "the order of evaluation is unspecified" ? Either you should throw away that book, or more likely the statement was in another context, e.g. arguments passed to functions can be avaluated in any order. – Jabberwocky Apr 15 '14 at 12:59
  • @JoachimPileborg Associativity is related to parsing, not to evaluation order. `a() + b() + c()` does not guarantee any ordering of the individual calls. – Angew is no longer proud of SO Apr 15 '14 at 13:18
  • @MichaelWalz: My source is [this link](http://en.cppreference.com/w/cpp/language/eval_order): "Order of evaluation of the operands of any C++ operator, including the order of evaluation of function arguments in a function-call expression, and the order of evaluation of the subexpressions within any expression is unspecified (except where noted below). The compiler will evaluate them in any order, and may choose another order when the same expression is evaluated again. There is no concept of left-to-right or right-to-left evaluation in C++, which is not to be confused with left-to-right ..." – martinvb Apr 16 '14 at 14:18
  • @martinvb : the information at that link is perfectly correct. But the && and the || operators are treated in a somewhat special manner. It's explaind unter "Sequence point rules" at the link you mention, but it is, admittedly, hard to understand. The answers below explain the concept in a simpler manner. – Jabberwocky Apr 16 '14 at 14:33

2 Answers2

3

Your and operator is more commonly written in C++ as &&, but they are both the same "logical and" operator. For this operator the order of evaluation is specified and evaluation is executed from left to right, guaranteed. (Otherwise millions of existing programs would fail).

The exception - not applicable to your code - is when the && operator is overloaded. In this case the left-to-right rule does not work. BTW it is a main reason why it is recommended not to overload this operator.

Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51
  • +1, but you might want to mention that this only applies when `&&` is not overloaded (and that in turn is cited as the primary reason *not* to overload `&&`). – Angew is no longer proud of SO Apr 15 '14 at 13:16
  • Thank you, this makes it very clear to me. :-) I did some more study on this subject, and [this post](http://stackoverflow.com/questions/555505/c-alternative-tokens/555517#555517) gives a clear view on many alternative names for operators. – martinvb Apr 16 '14 at 14:22
0

Your code below will work (I've changed 'and' to '&&' and added parentheses):

if ( (pCall != NULL) && (pCall->isDelivered() == false) ) {
   doSomething();
}

because the logical-AND && will 'short circuit'; i.e. if the first expression is false, the second will not be evaluated. Evaluation order is from left to right in this case.

The following relates to the Miscosoft C++ compiler in VS2013:

Logical operators also guarantee evaluation of their operands from left to right. However, they evaluate the smallest number of operands needed to determine the result of the expression. This is called "short-circuit" evaluation. Thus, some operands of the expression may not be evaluated. For example, in the expression x && y++ the second operand, y++, is evaluated only if x is true (nonzero). Thus, y is not incremented if x is false (0).

codah
  • 466
  • 4
  • 14
  • Thanks! I now learned that && is more common in C++ than `and', but they act the same. Furthermore, the `and'-keyword is not supported by C. Thank you all for the helpful comments and your efforts of making the geek world a better place. – martinvb Apr 16 '14 at 14:28