If I have a condition like this:
if (X && Y) {}
Will the compiler check Y
if X
is false? Is it compiler dependent?
If I have a condition like this:
if (X && Y) {}
Will the compiler check Y
if X
is false? Is it compiler dependent?
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.
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.
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
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.
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.