4

Possible Duplicate:
why “++x || ++y && ++z” calculate “++x” firstly ? however,Operator “&&” is higher than “||”

If you look at C's precedence table, you'll see that && has higher precedence than ||.

But take a look at the following code:

a=b=c=1;

++a || ++b && ++c;

printf("%d %d %d\n",a,b,c);

It prints out "2 1 1", meaning that the "++a" is evaluated first, and once the program sees a TRUE there it stops right there, because what is on the other side of the || is not important.

But since && has higher precedence than ||, shouldn't "++b && ++c" be evaluated first, and then the result plugged back into "++a || result" ? (in this case the program would print "1 2 2").

Community
  • 1
  • 1
Daniel Scocco
  • 7,036
  • 13
  • 51
  • 78

5 Answers5

13

Just try to imagine it with parentheses:

++a || ++b && ++c;

equals

(++a) || (++b && ++c);

which is evaluated from left to right.

if && and || would have the same precedence, it would look like

(++a || ++b) && (++c);
helios35
  • 1,577
  • 1
  • 14
  • 27
6

The precedence rules only say that it will be evaluated like this:

++a || (++b && ++c);

Now comes the short circuiting behavior of the logic operators which says that you have to evaluate terms from left to right and stop when the result is known. The part on the right never gets executed.

Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
2

Precedence and order of evaluation are two completely different things. For logical operator expressions, evaluation is always left-to-right. The expression ++a || ++b && ++c is interpreted as

  1. Evaluate ++a
  2. If the result of 1 is zero, evaluate ++b && ++c

The expression is parsed as ++a || (++b && ++c); the whole expression is true if either of the subexpressions ++a or ++b && ++c is true.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

&& has higher precedence only in parse tree. But compiler optimizes the code as

if( !++a ) {
    ++b && ++c;
}
artyom.stv
  • 2,097
  • 1
  • 24
  • 42
  • How do you better like more to call it. Doesn't matter. – artyom.stv Sep 23 '11 at 14:16
  • The idea that short-circuiting is an "optimization" is a misunderstanding that comes up on SO again and again. In many cases, **not** short-circuiting would be the optimization. For example, `++a|++b` (branchless) is almost certainly cheaper to compute than `++a||++b` (conditional branch). What's important to realize is that short-circuiting is not optional behavior, and the results are different. – R.. GitHub STOP HELPING ICE Sep 23 '11 at 14:59
  • Thanks, good to know that such behavior is not optional. I was too lazy to open standard to look this small issue. Anyway I think it is a bad practice to write "assignment" operators in conditions (any kind assigment) - new compilers generate very well optimized code (no need to make such optimizations as assignment in condition yourself). – artyom.stv Sep 23 '11 at 20:42
  • There are plenty of places where you end up with expressions with side effects in a conditional or a logical and/or, even if you don't write an assignment there. Function calls would be an obvious example. – R.. GitHub STOP HELPING ICE Sep 23 '11 at 20:55
0

Your example ++a || ++b && ++c is the same as ++a || (++b && ++c).

Kusalananda
  • 14,885
  • 3
  • 41
  • 52