4

If I have a condition like this:

if (X && Y) {}

Will the compiler check Y if X is false? Is it compiler dependent?

Iceman
  • 4,202
  • 7
  • 26
  • 39
  • if it's really empty like that the compiler will probably optimize it out and neither will be checked. :) – Mike Mar 26 '13 at 13:29
  • Probably duplicated: http://stackoverflow.com/questions/628526/is-short-circuiting-boolean-operators-mandated-in-c-c-and-evaluation-order – Oscar Foley Mar 26 '13 at 13:29
  • the check is done in the execution runtime and not in the compilation phase – MOHAMED Mar 26 '13 at 13:30
  • @Mike: If there's a function call involved I highly doubt that any compiler will optimize it away - unless it knows for sure that the function call does not have any side-effects. – ThiefMaster Mar 26 '13 at 18:49
  • @ThiefMaster - true, a simple type (`int`, `char`, ...) was assumed for that comment – Mike Mar 26 '13 at 18:50
  • Also, I did not mean an empty if-block either :) – Iceman Mar 26 '13 at 20:50

5 Answers5

10

In C and most other languages short-circuit evaluation is guaranteed. So Y is only evaluated if X evaluates to true.

The same applies to X || Y - in this case Y is only evaluated if X evaluates to false.

See Mike's answer for a reference to the C specification where this behavior is mentioned and guaranteed.

Community
  • 1
  • 1
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • isn't C allowed to evaluate `Y` first, then maybe `X`? – John Dvorak Mar 26 '13 at 13:29
  • 2
    No, not at all. That would actually be horrible: `if(x && x->foo)` - what if `x` was NULL? – ThiefMaster Mar 26 '13 at 13:29
  • In that case, you'd need to check `x` and then `x->foo`, in two separate `if` statements I distinctly remember having done this. – John Dvorak Mar 26 '13 at 13:33
  • 1
    @JanDvorak - see my answer below. It's in the C specification that it will be left-to-right evaluation. You may have had to do it for the bit-wise operator.. or maybe you had a non-compliant C compiler. ;) – Mike Mar 26 '13 at 13:46
7

The C specs (6.5.13) clarifies this point for you:

4 Unlike the bitwise binary & 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 equal to 0, the second operand is not evaluated.

So the C language itself defineds that if X == 0 then Y will not be checked.

Mike
  • 47,263
  • 29
  • 113
  • 177
3

the Y is checked only if the X is true

If X is false then Y will not be checked

BTW The check is done in the execution runtime and not in the compilation phase

MOHAMED
  • 41,599
  • 58
  • 163
  • 268
1

Both the && and || force left-to-right evaluation. Both will introduce a sequence point between the first and second operands if the second operand is evaluated. Neither will evaluate the second operand if the result of the expression can be determined from the first operand alone. IOW, for X && Y, Y will not be evaluated if X is false, whereas for X || Y, Y will not be evaluated if X is true.

Note that precedence does not affect order of evaluation; given an expression like X || Y && Z, Y && Z will not be evaluated before X, even though && has higher precedence than ||. X is evaluated first; if the result is 0 (false), then Y is evaluated. If that result is non-zero (true), then Z is evaluated.

This is defined in sections 6.5.13 and 6.5.14 of the language standard (2011 version, online draft), so it is not compiler-dependent.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

If Y has side-effects, or if accessing it might be undefined behavior (e.g. bad pointer dereference), then the compiler must ensure that Y is not evaluated unless X evaluated to true. However, if both X and Y lack side effects and the compiler knows access to them is well-defined, it might choose to optimize in such a way that both accesses happen.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711