Why does ++x || ++y && ++z
calculate ++x
first, even though the precedence of operator &&
is higher than ||
?

- 730,956
- 141
- 904
- 1,278

- 937
- 1
- 9
- 15
-
24I'm always amazed at how many questions are similar to this. Are people itching to write code like this? – President James K. Polk Sep 13 '10 at 12:33
-
22Ugh! Why do you care? Redo your code so that there is no confusion. – pmg Sep 13 '10 at 12:33
-
7@gnibbler: you're wrong. `||` and `&&` introduce sequence points, so the order is well-defined. It would even be valid to use the same variable for all three increments. – R.. GitHub STOP HELPING ICE Sep 13 '10 at 12:36
-
@R.., yes you are correct, I was thinking of bitwise operators – John La Rooy Sep 13 '10 at 12:48
-
4...and that is why you should *always* use parenthesis, even if the operators bind in the sequence you want them to - to make your intentions explicit and avoid just being plain wrong. ;-) – DevSolar Sep 13 '10 at 12:51
-
1@GregS: no I don't think that these types of questions correspond to real world problems. I guess most of them are just homework, exam question stuff like that. – Jens Gustedt Sep 13 '10 at 13:04
-
In my font `||` is highter than `&&`. – Johannes Schaub - litb Sep 13 '10 at 13:15
-
In mine they're roughly the same. But `||` is definitely lower. – Matt Joiner Sep 13 '10 at 13:30
-
2I'll never understand why silly questions get answers with so many upvotes... – Matt Joiner Sep 13 '10 at 13:31
-
1@DevSolar: Except that this particular question doesn't have all that much to do with precedence. With either possible precedence, or any legal use of parentheses, the evaluation is left to right. – David Thornley Sep 13 '10 at 14:21
-
I'm beginning to think questions like this are planted reputation-factories... ;-) – R.. GitHub STOP HELPING ICE Sep 13 '10 at 17:54
-
@Matt: I think it's because there were initially a few very bad answers with misleading information - everyone felt compelled to bump the correct answers up above them. – R.. GitHub STOP HELPING ICE Sep 14 '10 at 03:49
-
It's (hopefully) unlikely this is a real-world line of code. The OP probably stumbled upon this situation in something else and phrased this question by extracting it down to it's most simplest premise. – micnguyen Jul 25 '13 at 06:25
11 Answers
Huh?
If you're saying that &&
binds tighter than ||
(which is true), the expression is then equivalent to
++x || (++y && ++z)
Since ||
short-circuits, it needs to evaluate the left-hand side first.
If you mean that it ought to be equivalent to
(++x || ++y) && ++z
The same is still true, since &&
also short-circuits, meaning the ||
needs to be evaluated first, which in turn makes ++x
the first thing to evaluate.

- 56,865
- 12
- 98
- 126

- 391,730
- 64
- 469
- 606
Since &&
has higher precedence than ||
, it means your expression is equivalent to:
++x || (++y && ++z)
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 if x
, y
, and z
were all the same variable, since ||
and &&
introduce sequence points.

- 208,859
- 35
- 376
- 711
-
Thanks jk. Actually I just changed my whole answer because I had the precedence wrong, but hopefully the new version is at least as detailed and more accurate. – R.. GitHub STOP HELPING ICE Sep 13 '10 at 12:42
-
1R.., I'm astounded that you got this wrong at first (I expect better of you!), but the new answer is spot on =) – Stephen Canon Sep 13 '10 at 15:24
Unwind, R and others have explained what really happens. So let me just add:
The premise of your question is faulty. The fact that the &&
has higher precedence doesn't mean that operands that surround it must be evaluated before any operands in the expression with lower precedence. Even where the special case short-circuiting of ||
and &&
this wouldn't necessarily be so.
For example, consider a=b+c+d*e
; *
has higher precedence than +
, but that doesn't mean that d*e
must be evaluated before b+c
. It just means that it must be evaluated before we add the product to the expression as a whole. A compiler could evaluate this expression as temp1=d*e
, temp2=b+c
, a=temp1+temp2
or it could evaluate temp1=b+c
, temp2=d*e
, a=temp1+temp2
. Both would be equally valid.
With the short-circuiting behavior of ||
and &&
, there are some additional restrictions placed on order of evaluation.
As a side note: In general I would avoid writing code like this. I can easily see another programmer trying to read this code getting confused about just when the increments will happen and when they won't. Well, maybe if you used real variable names it would not look so bizarre.
I do occasionally rely on short-circuiting preventing side effects. Like
if (!eof() && readNextInt()>0)
I'm relying on the short-circuit to prevent reading if we're already at end of file, Or
if (confirmDelete==YES && deleteEntry()!=-1)
I'm relying on the first test to short-circuit on false so I don't do the delete when I shouldn't. But these examples seem pretty straightforward to me, I'd hope any competent programmer would see what I'm doing. But when the examples get cryptic, I think it needs to be broken out. Consider
if (customerType==RETAIL || lastDepositAmount()>100.00)
If lastDepositAmount()
had a side effect, then if customerType
is retail this side effect will never happen. I don't think that would necessarily be obvious to a reader. (Partly because the function name implies that it is retrieving data and not performing any update, and partly because there is no obvious relationship between the customer type and the amount of a deposit -- these sound like two independent things.) Admittedly, this is subjective. But when in doubt, choose simplicity and clarity over a trivial performance improvement. Always choose simplicity and clarity over "hey this is a way cool use of an obscure feature, anyone reading this will be impressed at how smart I must be to understand the language well enough to do this".

- 26,876
- 10
- 61
- 112
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 to False
, no matter the value of a
, in particular even if a
is not a single value but instead a complex expression. Therefore we don’t evaluate a
at all. Likewise, True || a
always resolves to True
.
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
.

- 530,221
- 131
- 937
- 1,214
-
Just a style note on your answer: I was confused at first by your use of "x" in the paragraph beginning "When is this the case?" because "x" is also part of the example, I thought you were referring to the same "x". Had to read that twice. – Jay Sep 13 '10 at 13:40
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.

- 64,414
- 37
- 100
- 175
-
Thank you, I like your answer too. Understanding the Polish tree and optimizations is key to understanding the answer for the question. That's why I've made the diagram. Note that it's not perfect because ++ is a node of the tree and x, y or z is the child of the given operation, but I sacrificed 100% correctness to make sure that we're talking about ++x and not x++. – Lajos Arpad Sep 13 '10 at 17:58
-
Firstly, it is incorrect to say that operators in general are evaluated in accordance with some tree. In reality, there's virtually no ordering in operator evaluation, unless it is a *special* operator. Operators like `&&`, `||` and `,` are actually special. Secondly, the fact that the evaluation is short-circuited is not an optimization (i.e. it is not a compiler optimization), it is a native property of operators `&&` and `||`. – AnT stands with Russia Sep 09 '11 at 04:07
-
First of all, there IS a priority relation between operators, for instance X + Y * Z is a good example. Y * Z will always be calculated before the +, because * has a higher priority than +. So, you are wrong here, there is an ordering in operator evaluation. – Lajos Arpad Sep 09 '11 at 12:25
-
Secondly, you can always look at these orders using the Polish tree. I'm not sure that precisely this was implemented in the compilers, but actually I can prove matematically that the Polish tree is accurate in organizing the operators. If you are interested, you can ask a question regarding this and please put a link to your question in a comment here if you want a proof. – Lajos Arpad Sep 09 '11 at 12:28
-
Thirdly, the second operand of the && operator won't be taken into account if the first is false, the second operand of the || operator won't be taken into account when the first was true. This is a useful way for optimization, because when an operand is a function with high complexity, it's usually better to make it the second operand, also, it's good to order your operands from unprobable to probable for && and to order your operators from probable to unprobable for ||. As you can see there are some options for optimization and you were wrong regarding this too. – Lajos Arpad Sep 09 '11 at 12:31
-
Last, but not least, please take a look here: http://www.difranco.net/cop2220/op-prec.htm – Lajos Arpad Sep 09 '11 at 12:35
-
@Lajos Arpad: Absolutely incorrect. C language has no "before" or "after" ordering unless there are *sequence points* involved. The `X + Y * Z` expression has no sequence points inside, which means that there's no way to say what happens "before" and what happens "after" There's no such thing as "priority" in C language that dictates the order of evaluation. – AnT stands with Russia Sep 14 '11 at 17:57
-
As it has been stated many times before, operator precedence in C has a purely syntactical meaning: it shows which operands belong to which operators. No more. It has absolutely no effect on the order of evaluation. Your table shows exactly that: a list of syntactical priorities. What I should "take a look" and what I should see there is not clear to me. The `a || b && c` expression is actually a good example of how precedence is totally unrelated from the order of evaluation: even though `&&` has higher precedence, it is `||` that will be processed first. – AnT stands with Russia Sep 14 '11 at 18:00
-
The `X + Y * Z` expression can be evaluated by the compiler as `(X + Y) + (Y * (Z - 1))` if it so desires. Claiming that the compiler must evaluate `Y * Z` first is laughable at best. There's one axiom of C language that you need to understand: the notion of *time* in C language is defined by *sequence points*. There are things that happen *before* some sequence point and there are things that happen *after* some sequence point. – AnT stands with Russia Sep 14 '11 at 18:04
-
If you are looking at something that have no sequence points inside (like `X + Y * Z` expression), then there's no "time", no "first", no "next", no "before" and no "after" there. Any attempts to introduce sequencing in it (like with some "Polish trees" or anything else) is a useless waste of time that only leads to useless and generally incorrect conclusions. – AnT stands with Russia Sep 14 '11 at 18:05
-
I'm interested when will be 1 + 2 * 3 = 9. It will always be 7, my friend, so you can laugh as much as you want if that makes you happy, however, I will believe you as soon as you show me an example where after processing the int x = 1 + 2 * 3 operation x will hold 9. Until then let me believe in my "useless waste of time". Also, please note that I have not mentioned anything about sequence points, I've answered a question about the results of calculations where multiple operators are used. – Lajos Arpad Dec 06 '11 at 12:03
-
Maybe you can save us from this "laughable at best" "useless waste of time" if you share your wisdom with us. Maybe we've waited long enough for your answer to finally see your insight which might not exist here. – Lajos Arpad Dec 06 '11 at 12:06
++ 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.

- 64,563
- 18
- 145
- 216
Precedence and order of evaluation are not the same thing, especially in this case. All precedence tells you is that the expression should be parsed as
++x || (++y && ++z)
IOW, it means that the expressions being OR'd together are ++x
and (++y && ++z)
. It does not mean that (++y && ++z)
will be evaluated before ++x
.
For the logical operators ||
and &&
, evaluation is always left-to-right (Online C Standard, Sections 6.5.13 and 6.5.14). For any expression
a || b
a
will be completely evaluated; b
will not be evaluated unless the result of a
is 0 (think of a
standing in for ++x
and b
standing in for ++y && ++z
). Similarly, for any expression
a && b
a
will be completely evaluated; b
will not be evaluated unless the result of a
is not 0.
So for your case, the expression ++x
is evaluated first. If the result is 0, only then will ++y && ++z
be evaluated.
||
and &&
are special in that the order of evaluation is guaranteed to be left-to-right. That is not true of the bitwise or arithmetic operators. For example, in the expression
++x + ++y * ++z
the expressions ++x
, ++y
, and ++z
may be evaluated in any order; all precedence tells you is that the result of (y+1) * (z+1)
will be added to the result of x+1
.

- 119,563
- 19
- 122
- 198
Top two answers explain it rather well... I'd point out that || is "OrElse".
Right side doesn't get touched if left side is true. Left side of && (AndAlso) doesn't get touched if right side is false.
If you want both sides to get incremented, use | and &.
http://msdn.microsoft.com/en-us/library/2h9cz2eb(v=VS.80).aspx
A logical operation is said to be short-circuiting if the compiled code can bypass the evaluation of one expression depending on the result of another expression. If the result of the first expression evaluated determines the final result of the operation, there is no need to evaluate the second expression, because it cannot change the final result. Short-circuiting can improve performance if the bypassed expression is complex, or if it involves procedure calls.
MSDN has tables that show how parts are "(not evaluated)".
Why touch part 2, if Part 1 pre-determines the outcome deterministically?

- 2,137
- 6
- 31
- 51
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.

- 607
- 1
- 8
- 18
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.

- 9,104
- 3
- 22
- 35
-
Irrelevant; there's nothing implementation-defined in this example. – R.. GitHub STOP HELPING ICE Sep 13 '10 at 12:37
-
2@R: Now that you commented and down voted on everyones posts about that thing you can maybe write your own answer and explain ... – Cedric H. Sep 13 '10 at 12:39
-
1@Cedric: Except that there are a good many wrong answers here, some of which have been corrected, and R.'s answer is a good one. – David Thornley Sep 13 '10 at 14:24
-
@David: I think my comment was before R.'s answer (or at least I didn't see it at that moment). – Cedric H. Sep 13 '10 at 14:32
No no no
if (++x || ++y && ++z) { /* ... */ }
Yes
++x;
++y;
++z;
if (x || (y && z)) { /* ... */ }
Edit after peer complaints :)
YES!
if (is_data_valid(x, y, z)) process_data(&x, &y, &z);

- 106,608
- 13
- 126
- 198
-
10Those codes don’t do the same thing! They are **not** equivalent. – Konrad Rudolph Sep 13 '10 at 12:38
-
1your answer is nevertheless misleading. And while the original code is certainly a no-go, similar problems arise from code that is, in its turn, completely sensible. – Konrad Rudolph Sep 13 '10 at 12:42
-
5yes, the original code is horrible, but in the original case for any non 0 value of x after increment ++y and ++zz wouldn't be executed at all. Even if a code is poorly written it does not mean you can replace it with a code doing something else. – kriss Sep 13 '10 at 12:45