x = y = z = 1;
z = ++x||++y&&++z;
operator precedence is as follows --
(pre-increment) > && > ||
so answer should be--
1. 2||2 && 2
2. 2||1
3. 1
print x,y,z should be 2,2,1
but, answer is 2,1,1.
x = y = z = 1;
z = ++x||++y&&++z;
operator precedence is as follows --
(pre-increment) > && > ||
so answer should be--
1. 2||2 && 2
2. 2||1
3. 1
print x,y,z should be 2,2,1
but, answer is 2,1,1.
Precedence is not the same as order of evaluation. Precedence simply determines what operands and operators belong together. The exact order of evaluation is unspecified except with the logical operators, which are evaluated in strict left-to-right order to enable short-circuiting.
So because &&
has higher precedence, the variables are first grouped as follows:
(++x) || (++y && ++z)
Then, following left-to-right order, ++x
is evaluated. Given that ++x
is true, it is known that the entire expression is true. So expression evaluation is short-circuited. (++y && ++z)
never gets evaluated. Hence y and z never get incremented.
Expressions with logical operators &&
and ||
evaluate left to right:
C99, Section 6.5.14-4 Unlike the bitwise
|
operator, the||
operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to0
, the second operand is not evaluated.
Since x++
is not zero, the expression short-circuits evaluation of everything to the right of ||
, including their side effects. That's why only x++
is evaluated, so x
becomes 2
. The remaining variables stay at 1
, as they should.
There's no sequence point in the expression:
z = ++x || ++y && ++z;
between the pre-increment of z
and assignment to z
.
So, if the ++z
is actually evaluated, that puts you instantly into undefined behaviour territory and anything can happen. You are not permitted to modify the same object twice without an intervening sequence point. Annex C (from C99) lists all the sequence points and the controlling one here is following a full-expression (the entire calculation and assignment).
6.5 Expressions /2
states:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
However, given your initial value of x
as 1, the ++z
part of the expression is not evaluated, in this particular case. That doesn't make the expression itself any less dangerous since it will invoke UB in the case where the starting point is x == -1
and y != -1
.
In this case, the controlling part of the standard is 6.5.14 Logical OR operator /4
:
Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.
So, the ++x
is evaluated first and, because it evaluates to not-zero, ++y && ++z
is never evaluated. x
is incremented to 2
and z
is set to the "truthy" value of that, or 1
, y
remains untouched at 1
.