"Roshan Mathews" <rm******@gmail.com> wrote:

According to the precedence rules && has a higher precedence than

|| and both are 'left to right' associative. So in an expression

like

++i || ++j && ++k

where i, j, k are 0, -1, 0 (before the expression is evaluated),

shouldn't the && part be evaluated before the || part?

No. This higher precendence means nothing more than that a || b && c is

equal to a || (b && c), not to (a || b) && c. It says nothing about the

order in which any of the operands are evaluated.

This is just as true of * and +, or of [] and ==. [] having higher

precedence than == means that x == y[z] does evaluate to x == (y[z]),

not to the (nonsensical) (x == y)[z]. It does not mean that y and z are

evaluated before x.

There is a special case, however, for the && and || operators, which

guarantees the opposite of your what you suppose. They are said to

short-circuit; that is, they are required to be evaluated left-to-right,

and when the value of the entire expression is known, that value is

returned and no other operands are even looked at.

This means that ++i || ++j && ++k is handled like this:

Evaluate ++i. If this is true (non-zero), the whole expression is true

(to be precise, it is 1); stop here.

Ok, we now know that i used to be -1, and ++i was 0 (and since both

|| and && also introduce a sequence point, so is i, now; this is not

important in this example, but can be in other circumstances; e.g.,

it means that --i && a[i] does not invoke undefined behaviour).

Evaluate ++j. If it is zero, the sub-expression ++j && ++k is zero,

and since ++i is also zero if we've got this far, so is the entire

expression; if so, stop here.

Now we know that ++i was 0 and ++j was non-zero.

Evaluate ++k. If it's false, the expression is false (0); if it's

true (non-zero), the expression is true (specifically 1).

Richard