Evaluation of expression C

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 && had a greater advantage than || according to this logic ++j should be executed, but it never executes and the program outputs -2 2 0 1 . What's going on here? What are the intermediate steps?

+6
c ++ c expression
source share
8 answers

&& has a higher priority than || , which means that ++i || ++j && ++k ++i || ++j && ++k parsed as ++i || (++j && ++k) ++i || (++j && ++k) .

However, this does not alter the fact that RHS || only executed if LHS returns 0 .

Priority does not affect the evaluation order.

+14
source share

Priority does not affect the evaluation order (except when necessary - some subexpressions may be evaluated before others due to priority). For example, in simple terms:

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

although multiplication takes precedence over addition, the compiler can make function calls in any order that it likes, and it can call a() or b() before or after the multiplication. Obviously, he must evaluate c() and d() before he performs the multiplication. If these functions have side effects (for example, changing and using global variables), an uncertain evaluation order can lead to unexpected results.

However, for some operators, the standard defines a strict evaluation procedure. This can be said about the logic or operator || :

Unlike bitwise | operator, || the operator guarantees an assessment from left to right; There is a sequence point after evaluating the first operand. If the first operand compares not equal to 0, the second operand is not evaluated.

Thus, not only || provides an order guarantee, but also guarantees that under certain conditions the second operand will not be evaluated at all.

(he also says something similar for && - except that in this case the second operand is not evaluated if the first evaluates to 0. But in your example, || appears first).

Other operators that provide some sort of guarantee of order include a comma operator and a function call (which ensures that the arguments are evaluated, but not the order in which these arguments are evaluated).

+7
source share

C ++ uses lazy evaluation for logical operators.
If you write a || b a || b , and a is true, b will never evaluate, since the result will be true, even if b is false.
Similarly, a && b will not evaluate b if a is false.

Since ++i evaluates a plausible value, none of the other expressions are evaluated.

+4
source share

& & and || using a short circuit assessment, that is, in the expression a & ba is first evaluated, if it is false, then the whole expression is false and b is not evaluated. In a || b if a is true, b is not evaluated. Please note that if you overload && or || short circuit rules no longer apply. NTN

+1
source share

C makes a short circuit of logical expressions, so a ++i score is enough to understand that m must be true.

+1
source share
  • Operator || forces to evaluate from left to right, therefore the expression ++i fully evaluated with a result of -2 .
  • Operator || forces the point of the sequence, so a side effect is applied, and i now equal to -2 .
  • The result of ++i not 0, so ++j && ++k is not evaluated at all.
  • Since LHS is nonzero, the result of the whole expression is ++i || ++j && ++k ++i || ++j && ++k is 1 (true), which is assigned m .

In order to repeat what several people said, the priority and order of assessment are not the same thing.

+1
source share

If you accidentally want to enter:

 m = ++i | ++j & ++k; 

which outputs -2 3 1 -1

0
source share

m = ++ i || ++ j && ++ k;

Since && has a higher priority than || , so the expression is interpreted as ++i || (++j && ++k) ++i || (++j && ++k)

|| is a short circuit, so the right operand of || does not get a score because ++i returns a nonzero value.

0
source share

All Articles