1
#include <stdio.h>

int main(void) {
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 am trying to learn about associativity and precedence of operators in C. Here, The output comes out to be -2 3 0 1, but I think the output should be -2 3 1 1 because k is also pre-incremented. Why that won't be the answer? Thanks!

mazhar islam
  • 5,561
  • 3
  • 20
  • 41
John Lui
  • 1,434
  • 3
  • 23
  • 37
  • 3
    why would you waste time to execute the commands after || when the statement before is already true? – robin.koch Jul 07 '15 at 10:10
  • Whoa! After much searching, didnt find it, otherwise wouldn't have posted the question in the first place. Anyways, no need to downvote, and yeah, nice answer. :) – John Lui Jul 07 '15 at 10:17
  • Is the code not explained in the textbook and/or web page? Why would you want us to explain it, (again, again)? – Martin James Jul 07 '15 at 11:08

4 Answers4

5

the || has short-circuit evaluation, which means that the right hand side gets evaluated only if the left hand side is false. In your case this doesn't happen since both i and j have values different than 0after being incremented, so the ++k doesn't get executed

The same behavior occurs when you have a && in which the LHS expressions evaluates to false

bznein
  • 908
  • 7
  • 21
  • Does this happen with only `||` operator, or is true for any other operator too? Like `&&` , if LHS comes out to be `0` or `false`, then RHS is not evaluated? – John Lui Jul 07 '15 at 10:18
  • This is true also for the &&, thanks for pointing out, I'll edit my answer! – bznein Jul 07 '15 at 10:19
  • and, if it happens with any other operator too, please add that too. Thanks! :) – John Lui Jul 07 '15 at 10:20
  • @JohnLui: It's true for every *logic* operator. It does not apply to arithmetic and bitwise boolean operators. – datenwolf Jul 07 '15 at 10:42
4

The expression before the || is true so the part after the || that is the ++K does not get executed so k wont be incremented. Hence the value of K remains 0 and the value of m is one since the left of || is true and true || <anything> is always true.

Minions
  • 1,273
  • 1
  • 11
  • 28
2

1 || 0 = 1 and 1 || 1 = 0

So once the first condition is TRUE while evaluating statement with || operator there is no need to evaluate the second expression that is what is happening here.

Gopi
  • 19,784
  • 4
  • 24
  • 36
1

Don't get confused with Precedence and Order of evaluation.

The order of evaluation of logical OR || is left to right.

So if left = true then left || right will never execute right. In your code exactly same happened.

As you know, any non zero value treated as true in C, hence, ++i or -2 is true. So,

 m = ++i && ++j || ++k;
 m = (true && true) || bla bla bla; //right not even checked!
 m = true 
 m = 1

And you get the output as expected.

For experiment, instead of i = -3 try i = -1, then the scenario will be

 m = ++i && ++j || ++k;
 m = false && (not going to evaluate) || ++k;
 m = false || true;
 m = true 
 m = 1

And output will be: 0 2 1 1

mazhar islam
  • 5,561
  • 3
  • 20
  • 41
  • Wait, I got your point, but, since `&&` has a higher precedence than `||` wont that get executed first and then its result will be used for evaluating `||`? – John Lui Jul 07 '15 at 10:28
  • Oh! Sorry, got it. The answer has clear explanation of my doubt. Thanks for the help though. :) – John Lui Jul 07 '15 at 10:32
  • 1
    @JohnLui Precedence only guarantees that the expression in itself will be evaluated as `((++i) && (++j)) || ...`. But it has nothing to do with the order in which the operands of each operator gets evaluated! Take plain maths, `1 + 2 + 3 * 4` is guaranteed to be equal to `1 + 2 + (3 * 4)`, but the precedence rules doesn't tell you that you must start calculating `1+2` before you calculate `3*4`. You might as well do it the other way around. Math doesn't care, because you'll get the same result. In C programming however, two different orders of evaluation may cause different results. – Lundin Jul 07 '15 at 11:20