简体   繁体   中英

C operator precedence, logical vs unary in a++ && b++ || ++c

In the follwing code,

int a = 1, b = 2, c = 3, d;
d = a++ && b++ || c++;
printf("%d\n", c);

The output will be 3 and I get that or evaluates first condition, sees it as 1 and then doesn't care about the other condition but in c, unary operators have a higher precedence than logical operators and like in maths

2 * 3 + 3 * 4

we would evaluate the above expression by first evaluating product and then the summation, why doesn't c do the same? First evaluate all the unary operators, and then the logical thing?

Please realize that precedence is not the same concept as order of evaluation . The special behavior of && and || says that the right-hand side is not evaluated at all if it doesn't have to be. Precedence tells you something about how it would be evaluated if it were evaluated.

Stated another way, precedence helps describe how to parse an expression. But it does not directly say how to evaluate it. Precedence tells us that the way to parse the expression you asked about is:

      ||
      / \
     /   \
    &&   c++
   / \
  /   \
a++    b++

But then when we go to evaluate this parse tree, the short-circuiting behavior of && and || tells us that if the left-hand side determines the outcome, we don't go down the right-hand side and evaluate anything at all. In this case, since a++ && b++ is true, the || operator knows that its result is going to be 1, so it doesn't cause the c++ part to be evaluated at all.

That's also why conditional expressions like

if(p != NULL && *p != '\0')

and

if(n == 0 || sum / n == 0)

are safe. The first one will not crash, will not attempt to access *p , in the case where p is NULL. The second one will not divide by 0 if n is 0.


It's very easy to get the wrong impression abut precedence and order of evaluation. When we have an expression like

1 + 2 * 3

we always say things like "the higher precedence of * over + means that the multiplication happens first". But what if we throw in some function calls, like this:

f() + g() * h()

Which of those three functions is going to get called first? It turns out we have no idea. Precedence doesn't tell us that. The compiler could arrange to call f() first, even though its result is needed last. See also this answer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM