Search code examples
cif-statementlogical-or

Logical AND OR and increment precedence


I want to ask a question about the code below.

int a=1, b=3, c=1;

if((a||c--)&&(c&&b--)) printf("%d",b);
printf("%d %d %d",a,b,c);

Why does the code prints "21 2 1" rather than "1 2 0" ?

Thanks for your help.


Solution

  • Both || and && force left-to-right evaluation - the LHS is evaluated first and all side effects applied, then based on the result the RHS is evaluated.

    Both operators short-circuit:

    • for a || b, if a is non-zero, then the result of the expression is 1 regardless of the value of b, so b is not evaluated;
    • for a && b, if a is zero, then the result of the expression is 0 regardless of the value of b, so b is not evaluated.

    && has higher precedence than ||, so a || b && c is parsed as a || (b && c).

    Putting all that together, (a||c--)&&(c&&b--) is evaluated as follows:

    1. a || c-- is evaluated as follows:
      1. a is evaluated - its result is 1, so
      2. c-- is not evaluated; because of this c's value is not changed, and
      3. the result of the expression is 1
    2. c && b-- is evaluated as follows:
      1. c is evaluated - its result is 1, so
      2. b-- is evaluated - its result is 3; as a side effect b is decremented, and
      3. the result of the expression is 1
    3. both a || c-- and c && b-- evaluate to 1

    The values of a and c are unchanged (1 and 1, respectively), while b has been decremented and its value is now 2.