Logical AND, OR: Is left-to-right evaluation guaranteed?
Yes, it's guaranteed, otherwise such operators would lose much of their usefulness.
Important notice: this is valid only for the builtin &&
and ||
; if some criminal overloads them, they are treated as "regular" overloaded binary operators, so in this case both operands are always evaluated, and in unspecified order as usual. For this reason, never overload them - it breaks a hugely important assumption about the control flow of the program.
Relevant standard quotations
Builtin &&
and ||
have guaranteed short-circuit behavior
§5.14 ¶1
Unlike
&
,&&
guarantees left-to-right evaluation: the second operand is not evaluated if the first operand isfalse
.
§5.15 ¶1
Unlike
|
,||
guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the first operand evaluates totrue
.
If overloaded, they behave as "regular" binary operators (no short-circuit or guaranteed ordering of evaluation)
§13.5 ¶9
Operators not mentioned explicitly in subclauses 13.5.3 through 13.5.7 act as ordinary unary and binary operators obeying the rules of 13.5.1 or 13.5.2.
and &&
and ||
are not mentioned explicitly in these subclauses, so regular §13.5.2 holds:
§13.5.2 ¶1
A binary operator shall be implemented either by a non-static member function (9.3) with one parameter or by a non-member function with two parameters. Thus, for any binary operator
@
,x@y
can be interpreted
as eitherx.operator@(y)
oroperator@(x,y)
.
with no special provision for evaluating only one side or in a particular order.
(all quotations from the C++11 standard)
Is the order of evaluation of AND operator from left to right guaranted?
According to the C Standard (6.5.13 Logical AND operator)
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.
Is order guaranteed in an or expression
Will
ListEqualByComparer.TryGetOrCreate
always be called beforeEnumerableEqualByComparer.TryGetOrCreate
?
Yes, and as ||
is short-circuiting, the second call will only be made if the first call returns false
.
From the C# 5 specification, section 7.12.1:
When the operands of
&&
or||
are of typebool
, or when the operands are of types that do not define an applicableoperator &
oroperator |
, but do define implicit conversions tobool
, the operation is processed as follows:[...]
The operation
x || y
is evaluated asx ? true : y
. In other words,x
is first evaluated and converted to typebool
. Then, ifx
is true, the result of the operation istrue
. Otherwise,y
is evaluated and converted to typebool
, and this becomes the result of the operation.
Guarantee function call in logical AND expression
Yes, the order is guaranteed. From cppreference.com:
Every value computation and side effect of the first (left)
argument of the built-in logical AND operator&&
and the built-in
logical OR operator||
is sequenced before every value computation and
side effect of the second (right) argument.
Logical operators' precedence in C
There are three issues here:
- Order of precedence.
- Order of evaluation.
- Short circuiting of logical operators.
Order of precedence implies that ++a || ++b && ++c
is evaluated as ++a || (++b && ++c)
.
However, due to the short circuiting requirements of logical operators, ++a
is evaluated first. Only if that evaluates to false
will (++b && ++c)
be evaluated. In your case, ++a
evaluates to true
. Hence, (++b && ++c)
is never evaluated.
In C does the logical operator end if one side of a || is true?
abc(2)
will be called only if abc(1)
is false
According to C99 specification, logical OR operator says
The || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.
confusing behaviour of logical and (&&) and logic or (||) operators in c programming
&&
has higher precedence, according to conventional terminology. "Priority" gives a potentially (more) misleading impression.
Whatever you call it, it is not about order of operations, but rather about correctly identifying the operands of each operator. That &&
has higher precedence means that your declaration of a
is equivalent to
int a = printf("a") || (printf("b")&&printf("c")); // THIS
, as opposed to
int a = (printf("a")||(printf("b")) && printf("c"); // NOT THIS
Furthermore, the printf("a")
is executed first either way, because the left-hand operand of &&
and ||
is always evaluated before the right-hand one, and the right-hand operand is only evaluated at all if that is necessary to determine the result of the operation.
In your case, each printf
call will return 1 on success (if it is executed at all). The printf("a")
is executed first, per the rule for the operands of an ||
operator. Its result is enough to determine the overall result of that operation, so no part of the other operand is evaluated.
If you used parentheses to override the default grouping then the short-circuiting would be more narrowly scoped, with the result that ac
would be printed.
Has c++ standard specified the evaluation order of an operator&&(built-in)?
Yes, it's guaranteed for built-in logical AND operator and logical OR operator by the standard.
(emphasis mine)
[expr.log.and]/1
The && operator groups left-to-right. The operands are both contextually converted to bool. The result is
true
if both operands aretrue
andfalse
otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand isfalse
.
[expr.log.or]/1
The || operator groups left-to-right. The operands are both contextually converted to bool. The result is
true
if either of its operands istrue
, andfalse
otherwise. Unlike |, || guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the first operand evaluates totrue
.
Is there any guarantee to be sure the left side of && operator is always evaluated first?
[expr.log.and]/1 ... Unlike
&
,&&
guarantees left-to-right
evaluation: the second operand is not evaluated if the first operand is false.
Related Topics
Profiling the C++ Compilation Process
C++: Where to Initialize Variables in Constructor
Function Declaration Inside or Outside the Class
How to Get Total CPU Usage in Linux Using C++
How to Convert Cstring and Std::String Std::Wstring to Each Other
How to Use SQLite in a Multi-Threaded Application
Is There Any Reason to Use the 'Auto' Keyword in C++03
How to Make a Multiple-Read/Single-Write Lock from More Basic Synchronization Primitives
When Do I Really Need to Use Atomic<Bool> Instead of Bool
Should I Pass an Std::Function by Const-Reference
How Is the C++ Exception Handling Runtime Implemented
Passing as Const and by Reference - Worth It
Why Is the Empty Base Class Optimization (Ebo) Is Not Working in Msvc