3

I am working on a simple C program, but ran in to some confusion. Below is the code:

int main(void) {
  int i, j, k;
  i = 3;
  j = 4;
  k = 5;

  printf("%d ", i < j || ++j < k);
  printf("\n");  // LINE 1

  printf("%d %d %d", i, j, k);  // LINE 2

  return 0;
}

In the above program, the variable j starts off being 4. Then in the printf statement of line 1 we increment the value of j by 1(++j = 5).

So theoretically, I would assume that when j is printed in printf(line 2) it prints as 5, since we did an incrementation in line 1 for j. However, every time I run the code, line 2 prints the original value of j which was 4, and NOT 5.

Is there something I am missing?

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
sye
  • 201
  • 3
  • 4
  • 10
  • 2
    Why the down votes? The question gives a code example along with expected output and an explanation of the poster's thought process. – Joshua Schlichting Jan 25 '20 at 22:53
  • @JoshuaSchlichting probably because of the large number of 'short-circuit evaluation' duplicates? – Martin James Jan 26 '20 at 09:20
  • @MartinJames I just think it's strange that people are down voted for not knowing the answer to their own question. It feels like this: "If you don't know about short-circuit evaluation, you better not ask a question where that knowledge solves the problem, because you should have known to search for questions regarding short circuit evaluation." I don't think the questioner here knew to search for this problem, as they didn't seem suspicious of the OR operator in this case. They wouldn't have thought to do research on short-circuit evaluation. I'm open to being wrong about this... – Joshua Schlichting Jan 26 '20 at 20:15

6 Answers6

7

j is never incremented because ++j is never evaluated. The OR operator is satisfied when it first checks i < j.

Joshua Schlichting
  • 3,110
  • 6
  • 28
  • 54
  • Technically it is called ['lazy evaluation'](https://en.wikipedia.org/wiki/Lazy_evaluation) – JohanC Jan 26 '20 at 00:22
3

This is an example of short-circuiting evaluation. When a boolean expression is A || B, if A is true, there is no need to evaluate B, and most languages adhere to that.

In this case, i < j is true, so the ++j < k is ignored.

Michael Rogers
  • 1,318
  • 9
  • 22
1

This is a good example to learn "what is short-circuit evaluation". In the boolean expression (i < j || ++j < k) that you used above; || is the short-circuit OR. So, to get the result as TRUE in the boolean expression one being true of one condition is enough. When considering i

In brief the difference between | and || is | consider the both conditions whether the first one is true. But || nevwr consider or process the second condition if the first condition is true and it jumps to the next line.

1

Looking at this expression:

i < j || ++j < k

The preincrement operator ++ has the highest precedence followed by the less-than operator < followed by the logical OR operator ||. So it parses like this:

(i < j) || ((++j) < k)

The logical OR operator || evaluates to true (specifically the value 1) if either the left side or the right side evaluates to true. Because of this, it also has the property that the right side will not be evaluated if the left side evaluates to true, since the result of the whole expression is already known at that point. This is commonly referred to as short-circuit evaluation.

This behavior is dictated by section 6.5.14p3 of the C standard regarding the logical OR operator:

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.

Going back to the expression, i < j is evaluated first. The value of i is 3 and the value of j is 4, so 3 < 4 evaluates to 1. Because this is the value of the left side of the || operator, the result of the || operator is 1 and the right side ++j < k is not evaluated, so j is never incremented.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

This is a good example to learn "what is short-circuit evaluation". In the boolean expression (i < j || ++j < k) that you used above; || is the short-circuit OR. So, to get the result as TRUE in the boolean expression one being true of one condition is enough. When considering i

In brief the difference between | and || is | consider the both conditions whether the first one is true. But || nevwr consider or process the second condition if the first condition is true and it jumps to the next line.

0

This is called short-circuit evaluation. If i < j equates to true then ++j < k will not be evaluated.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76