Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logical operators' precedence in C [duplicate]

Tags:

c

#include <stdio.h>

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

The outputs are 1, 0, 0 by gcc 8.1.0. The &&‘s precedence should higher than ||.

Why are the b and c are still 0?

like image 666
Joshua Shi Avatar asked Jul 06 '18 15:07

Joshua Shi


3 Answers

There are three issues here:

  1. Order of precedence.
  2. Order of evaluation.
  3. Short circuiting of logical operators.

Order of precedence implies that ++a || ++b && ++c is evaluated as ++a || (++b && ++c).

However, due to the short circuiting requirements of logical operators, ++a is evaluated first. Only if that evaluates to false will (++b && ++c) be evaluated. In your case, ++a evaluates to true. Hence, (++b && ++c) is never evaluated.

like image 149
R Sahu Avatar answered Oct 22 '22 05:10

R Sahu


The expression ++a || ++b && ++c is grouped as ++a || (++b && ++c). But, the right hand side of || is only evaluated if ++a is 0, which it isn't.

like image 14
Bathsheba Avatar answered Oct 22 '22 06:10

Bathsheba


The logical OR operator || (as well as the logical AND operator &&) is one of the few operators that perform short circut operation.

Section 6.5.14 of the C standard says the following about the logical OR operator:

4 Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.

Because ++a evaluates to 1, the result of the || operator is guaranteed to be 1 and the right hand side is not evaluated. Also, because && has higher precedence than ||, the right side of the || operator is ++b && ++c, meaning that neither ++b or ++c is evaluated.

like image 2
dbush Avatar answered Oct 22 '22 07:10

dbush