Search code examples
clogical-operatorsshort-circuiting

Shortcircuiting of AND in case of increment / decrement operator


In the code below:

#include <stdio.h>

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

i was expecting the output to be:

a=0,b=1,c=1,d=0

because due to short circuiting in the line below, ie a-- returns 0 so the other part wont get executed right?

int d = a-- && --b;

The output is:

a = 0, b = 0, c = 1, d = 0

can anyone please explain?


Solution

  • int c = a || --b;
    

    In this line, the C standard requires the C implementation to evaluate a first and, if it is not zero, not to evaluate --b. Although -- has higher precedence than ||, that just means that -- is grouped with b for the purposes of determining the structure of the expression, not for purposes of evaluating it. The left side of an || operator must be evaluated before the right side and, if the left side is true, the right side must not be evaluated, even in part.

    So, after the above, b is not changed; it is still 1.

    int d = a-- && --b;
    

    As with ||, the left-hand side of the && is evaluated first. So a-- is evaluated. This changes a to 0. However, the value of a-- is a before the change, so it is 1. A value of 0 would prevent the right side from being evaluated (because, once we know the left side is zero, we know the value of the complete && expression is zero). But, since the left side is not zero, --b must be evaluated to finish the &&. This changes b to 0. “Short-circuiting” means the left side is evaluated first, but the right side is still evaluated when necessary.