Why does ++x || ++y && ++z
calculate ++x
first, even though the precedence of operator &&
is higher than ||
?
相关问题
- Multiple sockets for clients to connect to
- What is the best way to do a search in a large fil
- glDrawElements only draws half a quad
- Index of single bit in long integer (in C) [duplic
- Equivalent of std::pair in C
The operators are evaluated using the Polish tree datastructure, as in the diagram, and it's a depth-first evaluation algorithm. Let's give names to the operations: A = ++x B = ++y C = ++z D = B && C E = C || D Evaluation order: A, B, C, D, E. Of course, C has an optimisation and if A is true, then E will be evaluated as true without evaluating B C and D. Similarly, if B is false, then C won't be evaluated to optimize the evaluation speed.
++ has highest priority of all, as its pre increment. This means that the value of the result of this operation is passed to binary operators. However the interesting thing is the short circuit of ++x or'ed with the rest. If ++x is true then the rest may not be done at all.
Since
&&
has higher precedence than||
, it means your expression is equivalent to:Thus, before the program even begins evaluating the result of
&&
, it has to evaluate++x
to determine whether the right-hand operand of||
should even be evaluated (logical binary operators are "short-circuiting", meaning they do not evaluate the right-hand side if the left-hand side is sufficient to determine the result). There is nothing fishy or compiler-specific here. The behavior of this expression is specified exactly by the C standard and will be the same on any compiler. It would even work ifx
,y
, andz
were all the same variable, since||
and&&
introduce sequence points.There are horribly wrong answers here.
The order of evaluation of this expression is not implementation dependent. It is well-defined!
Since
&&
binds higher than||
, this expression is equivalent to++x || (++y && ++z)
. Furthermore, both&&
and||
are short-circuited, so if the left-hand side of the expression suffices to determine the value, the right-hand side is never evaluated.When is this the case? Well, we know that
False && a
always resolves toFalse
, no matter the value ofa
, in particular even ifa
is not a single value but instead a complex expression. Therefore we don’t evaluatea
at all. Likewise,True || a
always resolves toTrue
.This results in a very definite order of evaluation in this example: first
++x
, then (if at all)++y
and then (again: if at all)++z
.It has been a long time since I have worked with C, but if I remember correctly, ++ is a unary operator which always has precedent over binary operators. Makes sense if you think about it.
You shouldn't rely on perceived operator priority if your operations are order sensitive, as different compilers (and differing versions of the same one) could implement priorities differently.
Eitherway b definition ++x means that x must be incremented BEFORE it is used and so you would expect it to be given high prioroty in execution.