The order in which all the elements in the calculation of the full expression are evaluated is not defined. All that is required is that each subexpression fully checks the operands before evaluating it. In the case of a function call, the arguments can be evaluated in any order, and in fact, one argument can be partially evaluated at a time when another argument is fully evaluated.
First expand the macro:
printf("max of %d and %d is %d\n", x, increment(), ((x) > (increment()) ? (x) : (increment()));
(Unfortunately, there is another problem: if increment() greater than x , then it is called again. Make the MAX macro instead, so that the arguments are evaluated only once!)
All of the following sequences are possible. I omit the estimate of x here because it does not change.
- The second argument to
increment() calculated, followed by x > increment() , followed by any operand ?: . (This was probably the sequence you were expecting.) x > increment() followed by some operand ?: followed by the second argument of increment() .x > increment() , followed by the second argument of increment() , followed by any operand ?: .
All of them can give different results, and all of them are the correct interpretation of your code.
When you call several functions in one full expression, you must make sure that these functions either do not have side effects, or the side effects of each function do not change the behavior of any other function. Otherwise, compiling on another compiler (or another version of the same compiler!) Could have changed the result.
As an additional example, even the simply looking expression increment() > increment() has an unspecified result because the order in which the operands are evaluated is not defined; if the first operand is evaluated first, then the result will be false, otherwise it will be true.
In a more complex example ((a + b) * (c + d)) compiler can evaluate a , b , c and d in any order that he likes. All that is required is that a and b must be evaluated before a + b can be, c and d must be evaluated to c + d , and a + b and c + d must be evaluated to the final operator * .