0

I am having an issue I cannot understand. The output for a is 6, b is -6 but the c remains the same no matter what variable I initialize it with.

#include <stdio.h>
void main()
{
int a = 5, b = -7, c = 0, d;
d = ++a && ++b || ++c;
printf("\n%d%d%d%d", a, b, c, d);
}

Thank you.

MarcoM
  • 11
  • 2
  • 5
    Short-circuiting. – Christian Gibbons Apr 18 '18 at 20:43
  • Because `A || B` evaluates to true if `A` is true or `B` is true. If `A` is true, then you don't need to evaluate `B`, because the whole statement is true. `++a && ++b` is non-zero, hence it's evaluated as true, hence `++c` doesn't need to be evaluated and it doesn't get executed. – Pablo Apr 18 '18 at 20:44
  • 2
    Not only do you not need to evaluate `B`, a compiler is *forbidden* to generate code executing side effects in `B` if `A` evaluates to true. Related: for example `if (p == NULL || p->value == 0) ...` is safe even in case `p` can be `NULL`. – Daniel Schepler Apr 18 '18 at 20:48

1 Answers1

5

This is short-circuiting behavior, and a deliberate part of the C language.

When C finds an expression of the form:

(expression A) || (expression B)

And expression A is evaluated to be TRUE, it does not matter what expression B is!
It could be TRUE, or FALSE, but the overall expression will still be TRUE, because of the ||.

As a result, the C language will not even bother to evaluate the second-half: expression B. That part just gets skipped, and so the ++c is skipped and never evaluated.


Just for kicks, if you wanted to change this program so that ++c does happen, set b equal to -1, so that when you have ++b, it becomes 0 (false).

int a = 5, b = -1, c = 0, d;

Now, the expression will evaluate this way:

d = (6 && 0) || [ lazy, short-circuit evaluation ];
d =    0     || [ second expression is now required! ];
d =    0     ||  1;
d = 1;

Output:

6011
abelenky
  • 63,815
  • 23
  • 109
  • 159
  • 1
    It might be worth noting that `&&` also short-circuits if the first operand evaluates to `0` or `false`. So for example, if `a` starts as `-1`, then `b` will not be incremented, only `a` and `c`. – Daniel Schepler Apr 18 '18 at 21:01