Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evaluation of C expression

Tags:

c++

c

expression

int main() {
  int i = -3, j = 2,  k = 0, m;
  m = ++i || ++j && ++k;
  printf("%d %d %d %d\n", i, j, k, m);
  return 0;
}

i thought that && has more precedence that || as per this logic ++j should execute, but it never does and the program outputs -2 2 0 1. What is going on here? What are the intermediate steps?

like image 626
shreyasva Avatar asked Oct 12 '10 15:10

shreyasva


2 Answers

&& does have higher precedence than ||, which means that ++i || ++j && ++k parses as ++i || (++j && ++k).

However this does not change the fact that the RHS of || only executes if the LHS returns 0.

Precedence does not affect order of evaluation.

like image 121
sepp2k Avatar answered Oct 19 '22 20:10

sepp2k


Precedence doesn't have an effect on order of evaluation (except as necessary - some sub-expressions might need to be evaluated before others due to precedence). For example, in the simple expression:

a() + b() + c() * d()

even though multiplication has precedence over addition, the compiler is free to perform the calls to the functions in any order it likes, and might call a() or b() before or after it performs the multiplication. Obviously, it does have to evaluate c() and d() before it performs the multiplication. If these functions have side-effects (like modifying and using global variables), the indeterminate evaluation order could result in unexpected outcomes.

However, for some operators, the standard does prescribe a strict order of evaluation. It this to say about the || logical or operator:

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

So not only does the || provide an ordering guarantee, it also guarantees that under certain conditions, the 2nd operand won't be evaluated at all.

(it also says something similar for the && - except that in that case the 2nd operand isn't evaluated if the first evaluates to 0. But in your example, the || comes first).

Other operators that provide some guarantee of ordering include the comma operator and the function call (which guarantees that arguments have been evaluated, but not the order in which those arguments have been evaluated).

like image 40
Michael Burr Avatar answered Oct 19 '22 21:10

Michael Burr