1

Can someone explain how the following code functions

#include <stdio.h>

void main() {
    int a = 2, b = -1, c = 0, d;
    d = a-- || b++ && c++;
    printf("%d%d%d%d", a, b, c, d);
}

I was expecting the value to be 1010 since I have read that && has more priority than ||, hence it should be evaluated first. But the answer seems to be 1-101. Could someone explain why? I know about the short circuit evaluation rule, but just don't understand why b++ && c++ isn't performed first?

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Aevo
  • 70
  • 6
  • 3
    Short-circuit evaluation: the right part will be evaluated **only** if the first is false (0). – Jean-Baptiste Yunès Jun 12 '23 at 14:48
  • 1
    This might help you: https://stackoverflow.com/questions/628526/is-short-circuiting-logical-operators-mandated-and-evaluation-order – Erich Kitzmueller Jun 12 '23 at 14:49
  • Suppose `b++ && c++` were evaluated first. You evaluate `b++`. If it is false, you stop evaluating `b++ && c++` due to the nature of `&&`. If it is true, you evaluate `c++`. Then, either way, you know the result of `b++ && c++`. So you have evaluated `b++ && c++` first. But you know `||` is supposed to evaluate its left operand first. So how could that work? For `||` to evaluate its left operand first, it must evaluate its left operand first. – Eric Postpischil Jun 12 '23 at 15:08

1 Answers1

6

Operator precedence dictates how operands are grouped, not how they are evaluated.

Since && has higher precedence than ||, this:

d = a-- || b++ && c++;

Is the same as this:

d = (a--) || ((b++) && (c++));

Now looking at this, we can see that the left operand of || is a-- and the right operand is b++ && c++. So a-- is evaluated first, and since the value of a is 2 this expression evaluates to 2. This makes the left side of || true, meaning that the right side, i.e. b++ && c++, is not evaluated. So because the left operand of || is nonzero, the result of the || operator 1.

So a is decremented to 1, d is assigned 1 because since that is the result of the || operator, and b and c are unchanged.

dbush
  • 205,898
  • 23
  • 218
  • 273