19

OK, I'm a little embarassed to ask this question, but I just want to be sure...

It is known that C uses short circuit evaluation in boolean expressions:

int c = 0;
if (c && func(c)) { /* whatever... */ }

In that example func(c) is not called because c evaluates to 0. But how about more sophisticated example where side effects of comparison would change the variable being compared next? Like this:

int c; /* this is not even initialized... */
if (canInitWithSomeValue(&c) && c == SOMETHING) { /*...*/ }

Function canInitWithSomeValue returns true and changes value at given pointer in case of success. Is it guaranteed that subsequent comparisons (c == SOMETHING in this example) uses value set by canInitWithSomeValue(&c)?

No matter how heavy optimizations the compiler uses?

Łukasz Sromek
  • 3,637
  • 3
  • 30
  • 43
  • I think you may be confusing short circuit evaluation and compiler optimisation. In the first example, the compiler will optimise away that entire `if` statement, because it can never run. Short circuit-evaluation would mean that if you had `if(func1() && func2()) { ... }`, and func1() evaluated to false **at runtime** (i.e. not definetely when compiling), then the code should not check `func2()` - the compiler should have crafted the machine code such that if `func1()` is false, `func2()` isn't called. – Stephen Sep 03 '10 at 12:35
  • That `int c = 0` was there to indicate that `c` is equal to `0` at the time of comparision, I realize that in a case that simple the compiler would optimise the entire `if`. – Łukasz Sromek Sep 03 '10 at 12:53
  • Ah, I do apologise. I misread you. My apologies. – Stephen Sep 03 '10 at 13:46

3 Answers3

25

Is it guaranteed that subsequent comparisons (c == SOMETHING in this example) uses value set by canInitWithSomeValue(&c)?

Yes. Because there is a sequence point

Between evaluation of the left and right operands of the && (logical AND), || (logical OR), and comma operators. For example, in the expression *p++ != 0 && *q++ != 0, all side effects of the sub-expression *p++ != 0 are completed before any attempt to access q.


A sequence point defines any point in a computer program's execution at which it is guaranteed that all side effects of previous evaluations will have been performed, and no side effects from subsequent evaluations have yet been performed.

Amarghosh
  • 58,710
  • 11
  • 92
  • 121
5

Yes. Because both && and || operator are also something called sequence points. The latter define when the side-effects of a previous operation should be complete and those of the next should not have begun.

dirkgently
  • 108,024
  • 16
  • 131
  • 187
1

Evaluation within the if statement composite condition is strictly left to right. The only circumstance under which the second test in your if would be optimized out is if the compiler can determine with 100% certainty that the first is identically equal to false.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140