Precedence does not specify the order in which an expression is evaluated. It specifies how an expression is interpreted. In this case, the precedence rules of C (which are embedded in its formal grammar) cause a || b && c
to be interpreted as a || (b && c)
.
When this expression is evaluated, the rules of C specify that a
must be evaluated first. The rules also state that if a
is true, then value of the entire expression is true, and the right side of the ||
is not evaluated.
To see this more clearly, consider the expression a + b < c * d
. The precedence rules cause this to be interpreted as (a + b) < (c * d)
. However, unlike ||
, the rules of C do not specify that the left side of <
must be evaluated first. The compiler may evaluate a + b
first or c * d
first, even though *
has higher precedence than +
. The compiler is allowed to use any evaluation order that gets the right answer.
The only order imposed here is that a + b
and c * d
must both be evaluated before the <
can be evaluated. However, that comes from the structure of the expression, not the rules of precedence.