This takes advantage of a language feature known as "short circuiting".
With the below code:
'a' is evaluated first. If it results to nonzero (true), then the compiler knows that the || operator will also result in true, so it has no need to evaluate 'b'.
Similarly..
a && b
, if 'a' results in zero (false), then the compiler knows that the && will also result in false, so there's no need to evaluate 'b'.
This is often (ab)used to check to see if a pointer is null before dereferencing it:
1 2 3 4 5
|
MyClass* ptr = /*something, possibly null*/
if(ptr && ptr->something) // if the pointer is non-null, then dereference it and check 'something'
{
}
|
What's happening in your example is this:
1) ++x is being evaluated first, which results in 2 (nonzero, true), so the right side of the || operator is skipped
2) || has a lower operator precedent than &&, so
++y&&++z
is all considered the right side of the expression... just as if you had said:
++x || (++y && ++z)
, therefore, all of it is skipped.
End Result: only x was incremented. y and z increments were short circuited.
Compare that to
(++x || ++y) && ++z;
, which will increment both x and z, because the || short circuit will now only remove the y increment.