There is no sequence point in the expression:
z = ++x || ++y && ++z;
between the pre-increment z and the assignment z .
So, if ++z is actually evaluated, it instantly puts you in the undefined behavior area, and anything can happen. You are not allowed to modify the same object twice without an intermediate point. Appendix C (from C99) lists all points in the sequence, and the control one follows the full expression (all calculation and assignment).
6.5 Expressions /2 :
Between the previous and next points in the sequence, the object must have the changed value of the stored value no more than once by evaluating the expression. In addition, the previous value should only be read to determine the stored value.
However, given that your initial x value is 1, part of the ++z expression is not evaluated in this particular case. This does not make the expression itself less dangerous, since it will call UB when the starting point is x == -1 and y != -1 .
In this case, the control part of the standard 6.5.14 Logical OR operator /4 :
Unlike bitwise | operator, || the operator guarantees evaluation from left to right; a sequence point appears after evaluating the first operand. If the first operand is compared to not equal to 0, the second operand is not evaluated.
So, ++x is evaluated first, and since it calculates a nonzero value, ++y && ++z never evaluated. x increases by 2 , and z set to the "true" value of this, or 1 , y remains untouched at 1 .
source share