int i=-1, j=-1, k=-1, l=2, m;
m = (i++ && j++ && k++) || (l++);
printf("%d %d %d %d %d", i, j, k, l, m);
0 0 0 2 1
0 0 0 3 1
Operator precedence (and associativity) only determines how the expression should be parsed. It is a common mistake to confuse it with order of evaluation of the operands, which is different thing. Operator precedence is rather irrelevant in this example.
For most operators in C, the order of evaluation of the operands is not specified. Had you written
true | l++ then
l++ would have been executed. The "short-circuit evaluation" is the reason why this doesn't happen in your code. The
&& || operators is a special case, since they explicitly define the order of evaluation. The right operand of
|| is guaranteed not to be evaluated in case the left operand evaluates to non-zero.