if(a && b)
{
do something;
}
is there any possibility to evaluate arguments from right to left(b -> a)?
if "yes", what influences the evaluation order?
(i'm using VS2008)
With C++ there are only a few operators that guarantee the evaluation order
operator && evaluates left operand first and if the value is logically false then it avoids evaluating the right operand. Typical use is for example if (x > 0 && k/x < limit) ... that avoids division by zero problems.
operator || evaluates left operand first and if the value is logically true then it avoids evaluating the right operand. For example if (overwrite_files || confirm("File existing, overwrite?")) ... will not ask confirmation when the flag overwrite_files is set.
operator , evaluates left operand first and then right operand anyway, returning the value of right operand. This operator is not used very often. Note that commas between parameters in a function call are not comma operators and the order of evaluation is not guaranteed.
The ternary operator x?y:z evaluates x first, and then depending on the logical value of the result evaluates either only y or only z.
For all other operators the order of evaluation is not specified.
The situation is actually worse because it's not that the order is not specified, but that there is not even an "order" for the expression at all, and for example in
std::cout << f() << g() << x(k(), h());
it's possible that functions will be called in the order h-g-k-x-f (this is a bit disturbing because the mental model of << operator conveys somehow the idea of sequentiality but in reality respects the sequence only in the order results are put on the stream and not in the order the results are computed).
Obviously the value dependencies in the expression may introduce some order guarantee; for example in the above expression it's guaranteed that both k() and h() will be called before x(...) because the return values from both are needed to call x (C++ is not lazy).
Note also that the guarantees for &&, || and , are valid only for predefined operators. If you overload those operators for your types they will be in that case like normal function calls and the order of evaluation of the operands will be unspecified.
Changes since C++17
C++17 introduced some extra ad-hoc specific guarantees about evaluation order (for example in the left-shift operator <<). For all the details see https://stackoverflow.com/a/38501596/320726
The evaluation order is specified by the standard and is left-to-right. The left-most expression will always be evaluated first with the && clause.
If you want b to be evaluated first:
if(b && a)
{
//do something
}
If both arguments are methods and you want both of them to be evaluated regardless of their result:
bool rb = b();
bool ra = a();
if ( ra && rb )
{
//do something
}
In this case, since you're using &&, a will always be evaluated first because the result is used to determine whether or not to short-circuit the expression.
If a returns false, then b is not allowed to evaluate at all.
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.
Read here for a more exhaustive explanation of the rules set:
order evaluation
It will evaluate from left to right and short-circuit the evaluation if it can (e.g. if a evaluates to false it won't evaluate b).
If you care about the order they are evaluated in you just need to specify them in the desired order of evaluation in your if statement.
The built-in && operator always evaluates its left operand first. For example:
if (a && b)
{
//block of code
}
If a is false, then b will not be evaluated.
If you want b to be evaluated first, and a only if b is true, simply write the expression the other way around:
if (b && a)
{
//block of code
}
Related
Does the ANSI standard mandate the logical operators to be short-circuited, in either C or C++?
I'm confused for I recall the K&R book saying your code shouldn't depend on these operations being short circuited, for they may not. Could someone please point out where in the standard it's said logic ops are always short-circuited? I'm mostly interested on C++, an answer also for C would be great.
I also remember reading (can't remember where) that evaluation order isn't strictly defined, so your code shouldn't depend or assume functions within an expression would be executed in a specific order: by the end of a statement all referenced functions will have been called, but the compiler has freedom in selecting the most efficient order.
Does the standard indicate the evaluation order of this expression?
if( functionA() && functionB() && functionC() ) cout<<"Hello world";
Yes, short-circuiting and evaluation order are required for operators || and && in both C and C++ standards.
C++ standard says (there should be an equivalent clause in the C standard):
1.9.18
In the evaluation of the following expressions
a && b
a || b
a ? b : c
a , b
using the built-in meaning of the operators in these expressions, there is a sequence point after the evaluation of the first expression (12).
In C++ there is an extra trap: short-circuiting does NOT apply to types that overload operators || and &&.
Footnote 12: The operators indicated in this paragraph are the built-in operators, as described in clause 5. When one of these operators is overloaded (clause 13) in a valid context, thus designating a user-defined operator function, the expression designates a function invocation, and the operands form an argument list, without an implied sequence point between them.
It is usually not recommended to overload these operators in C++ unless you have a very specific requirement. You can do it, but it may break expected behaviour in other people's code, especially if these operators are used indirectly via instantiating templates with the type overloading these operators.
Short circuit evaluation, and order of evaluation, is a mandated semantic standard in both C and C++.
If it wasn't, code like this would not be a common idiom
char* pChar = 0;
// some actions which may or may not set pChar to something
if ((pChar != 0) && (*pChar != '\0')) {
// do something useful
}
Section 6.5.13 Logical AND operator of the C99 specification (PDF link) says
(4). Unlike the bitwise binary & operator, the && operator guarantees
left-to-right evaluation; there is a
sequence point after the evaluation of
the first operand. If the first
operand compares equal to 0, the
second operand is not evaluated.
Similarly, section 6.5.14 Logical OR operator says
(4) Unlike the bitwise | operator, 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.
Similar wording can be found in the C++ standards, check section 5.14 in this draft copy. As checkers notes in another answer, if you override && or ||, then both operands must be evaluated as it becomes a regular function call.
Yes, it mandates that (both evaluation order and short circuit). In your example if all functions return true, the order of the calls are strictly from functionA then functionB and then functionC. Used for this like
if(ptr && ptr->value) {
...
}
Same for the comma operator:
// calls a, then b and evaluates to the value returned by b
// which is used to initialize c
int c = (a(), b());
One says between the left and right operand of &&, ||, , and between the first and second/third operand of ?: (conditional operator) is a "sequence point". Any side effects are evaluated completely before that point. So, this is safe:
int a = 0;
int b = (a++, a); // b initialized with 1, and a is 1
Note that the comma operator is not to be confused with the syntactical comma used to separate things:
// order of calls to a and b is unspecified!
function(a(), b());
The C++ Standard says in 5.14/1:
The && operator groups left-to-right. The operands are both implicitly converted to type bool (clause 4).
The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right
evaluation: the second operand is not evaluated if the first operand is false.
And in 5.15/1:
The || operator groups left-to-right. The operands are both implicitly converted to bool (clause 4). It returns true if either of its operands is true, and false otherwise. Unlike |, || guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the first operand evaluates to true.
It says for both next to those:
The result is a bool. All side effects of the first expression except for destruction of temporaries (12.2) happen before the second expression is evaluated.
In addition to that, 1.9/18 says
In the evaluation of each of the expressions
a && b
a || b
a ? b : C
a , b
using the built-in meaning of the operators in these expressions (5.14, 5.15, 5.16, 5.18), there is a sequence point after the evaluation of the first expression.
Straight from good old K&R:
C guarantees that && and || are evaluated left to right — we shall soon see cases where this matters.
Be very very careful.
For fundamental types these are shortcut operators.
But if you define these operators for your own class or enumeration types they are not shortcut. Because of this semantic difference in their usage under these different circumstances it is recommended that you do not define these operators.
For the operator && and operator || for fundamental types the evaluation order is left to right (otherwise short cutting would be hard :-) But for overloaded operators that you define, these are basically syntactic sugar to defining a method and thus the order of evaluation of the parameters is undefined.
Your question comes down to C++ operator precedence and associativity. Basically, in expressions with multiple operators and no parentheses, the compiler constructs the expression tree by following these rules.
For precedence, when you have something like A op1 B op2 C, you could group things as either (A op1 B) op2 C or A op1 (B op2 C). If op1 has higher precedence than op2, you'll get the first expression. Otherwise, you'll get the second one.
For associativity, when you have something like A op B op C, you could again group thins as (A op B) op C or A op (B op C). If op has left associativity, we end up with the first expression. If it has right associativity, we end up with the second one. This also works for operators at the same precedence level.
In this particular case, && has higher precedence than ||, so the expression will be evaluated as (a != "" && it == seqMap.end()) || isEven.
The order itself is "left-to-right" on the expression-tree form. So we'll first evaluate a != "" && it == seqMap.end(). If it's true the whole expression is true, otherwise we go to isEven. The procedure repeats itself recursively inside the left-subexpression of course.
Interesting tidbits, but the concept of precedence has its roots in mathematic notation. The same thing happens in a*b + c, where * has higher precedence than +.
Even more interesting/obscure, for a unparenthasiszed expression A1 op1 A2 op2 ... opn-1 An, where all operators have the same precedence, the number of binary expression trees we could form is given by the so called Catalan numbers. For large n, these grow extremely fast.
d
If you trust Wikipedia:
[&& and ||] are semantically distinct from the bit-wise operators & and | because they will never evaluate the right operand if the result can be determined from the left alone
C (programming language)
if(a && b)
{
do something;
}
is there any possibility to evaluate arguments from right to left(b -> a)?
if "yes", what influences the evaluation order?
(i'm using VS2008)
With C++ there are only a few operators that guarantee the evaluation order
operator && evaluates left operand first and if the value is logically false then it avoids evaluating the right operand. Typical use is for example if (x > 0 && k/x < limit) ... that avoids division by zero problems.
operator || evaluates left operand first and if the value is logically true then it avoids evaluating the right operand. For example if (overwrite_files || confirm("File existing, overwrite?")) ... will not ask confirmation when the flag overwrite_files is set.
operator , evaluates left operand first and then right operand anyway, returning the value of right operand. This operator is not used very often. Note that commas between parameters in a function call are not comma operators and the order of evaluation is not guaranteed.
The ternary operator x?y:z evaluates x first, and then depending on the logical value of the result evaluates either only y or only z.
For all other operators the order of evaluation is not specified.
The situation is actually worse because it's not that the order is not specified, but that there is not even an "order" for the expression at all, and for example in
std::cout << f() << g() << x(k(), h());
it's possible that functions will be called in the order h-g-k-x-f (this is a bit disturbing because the mental model of << operator conveys somehow the idea of sequentiality but in reality respects the sequence only in the order results are put on the stream and not in the order the results are computed).
Obviously the value dependencies in the expression may introduce some order guarantee; for example in the above expression it's guaranteed that both k() and h() will be called before x(...) because the return values from both are needed to call x (C++ is not lazy).
Note also that the guarantees for &&, || and , are valid only for predefined operators. If you overload those operators for your types they will be in that case like normal function calls and the order of evaluation of the operands will be unspecified.
Changes since C++17
C++17 introduced some extra ad-hoc specific guarantees about evaluation order (for example in the left-shift operator <<). For all the details see https://stackoverflow.com/a/38501596/320726
The evaluation order is specified by the standard and is left-to-right. The left-most expression will always be evaluated first with the && clause.
If you want b to be evaluated first:
if(b && a)
{
//do something
}
If both arguments are methods and you want both of them to be evaluated regardless of their result:
bool rb = b();
bool ra = a();
if ( ra && rb )
{
//do something
}
In this case, since you're using &&, a will always be evaluated first because the result is used to determine whether or not to short-circuit the expression.
If a returns false, then b is not allowed to evaluate at all.
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.
Read here for a more exhaustive explanation of the rules set:
order evaluation
It will evaluate from left to right and short-circuit the evaluation if it can (e.g. if a evaluates to false it won't evaluate b).
If you care about the order they are evaluated in you just need to specify them in the desired order of evaluation in your if statement.
The built-in && operator always evaluates its left operand first. For example:
if (a && b)
{
//block of code
}
If a is false, then b will not be evaluated.
If you want b to be evaluated first, and a only if b is true, simply write the expression the other way around:
if (b && a)
{
//block of code
}
Many times I see (and sometimes write) code similar to this example:
int a=0, b=2;
if( a && (b=func())!=0 ) {
//...
The question is: does the standard guarantee these statements?
b will be not touched (and remain value 2)
func() will not be called
And vice-versa, if we write if( func()!=0 && a ) - does the standard guarantee func() will be called?
I'm interested in the particular standard paragraph defining this is legitimate.
UPD: my typo, changed from int a=1 to int a=0
To the exact question;
The question is: does standard guarantee these statements?
To the updated question; given a=0. If a==0, then yes, the short circuit evaluation would kick in and func() would not be called; the second operand would not be evaluated.
If a=1 (as it was originally), the opposite; func() will be called - a is 1 thus "true", as a result the second operand is evaluated (it is a logical AND), b will change. If the operator had been || (logical OR), then short circuit evaluation would kick in and func() would not be called.
And vice-versa, if we write if( func()!=0 && a ) -- does standard guarantee func() will be called?
Yes, the first operand is always evaluated.
Yes, short circuit evaluation is guaranteed for C++;
§5.14 Logical AND operator
1 The && operator groups left-to-right. The operands are both contextually converted to bool (Clause 4). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
2 The result is a bool. If the second expression is evaluated, every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second expression.
§5.15 Logical OR operator
1 The || operator groups left-to-right. The operands are both contextually converted to bool (Clause 4). It returns true if either of its operands is true, and false otherwise. Unlike |, || guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the first operand evaluates to true.
2 The result is a bool. If the second expression is evaluated, every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second expression.
The corresponding quotes for C are;
§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.
§6.5.14 Logical OR operator
4 Unlike the bitwise | 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 unequal to 0, the second operand is not evaluated.
From the C-90 standard.
6.5.13 Logical AND operator
....
4 Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation;
there is a sequence point after the evaluation of the first operand. If the first operand
compares equal to 0, the second operand is not evaluated.
Similarly for the Logical OR operator.
The && operator requires both operands to be true. If the first operand evaluates to false, then the second operand will not be evaluated. But beause a is 1, it is considered true and the second expression (operand) is evaluated. Thus func() is called and its result assigned to b and then b is tested to be non-zero.
The standard guarantees that the statements in a sequence of && are evaluated from left to right, and that as soon as one of them evaluates to false, the ones to the right of that will not be evaluated.
The question is: does standard guarantee these statements?
b will be not touched (and remain value 2)
func() will not be called
No, in fact both of them wrong in this case. Because it's operator && so no shortcut logic can be applied in this particular case.
If you change it to || then your statements are correct - only then the evaluation of the first operand (a = 1 in this case) will be enough and the rest is ignored.
As the question changed to a = 0 then yes, both statements are correct and guaranteed.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Safety concerns about short circuit evaluation
What does the standard say about evaluating && expressions - does it guarantee that evaluation of parameters will stop at the first false?
E.g.:
Foo* p;
//....
if ( p && p->f() )
{
//do something
}
is the f() guaranteed not to be called if p == NULL?
Also, is the order of evaluation guaranteed to be the order of appearence in the clause?
Might the optimizer change something like:
int x;
Foo* p;
//...
if ( p->doSomethingReallyExpensive() && x == 3 )
{
//....
}
to a form where it evaluates x==3 first? Or will it always execute the really expensive function first?
I know that on most compilers (probably all) evaluation stops after the first false is encountered, but what does the standard say about it?
What does the standard say about evaluating && expressions - does it guarantee that evaluation of parameters will stop at the first false?
Yes. That is called short-circuiting.
Also, is the order of evaluation guaranteed to be the order of appearence in the clause?
Yes. From left to right. The operand before which the expression short-circuited doesn't get evaluated.
int a = 0;
int b = 10;
if ( a != 0 && (b=100)) {}
cout << b << endl; //prints 10, not 100
In fact, the above two points are the keypoint in my solution here:
Find maximum of three number in C without using conditional statement and ternary operator
In the ANSI C standard 3.3.13:
Unlike the bitwise binary & operator, the && operator guarantees
left-to-right evaluation; there is a sequence point after the
evaluation of the first operand. If the first operand compares equal
to 0, the second operand is not evaluated.
There is an equivalent statement in the C++ standard
&& (and ||) establish sequence points. So the expression on the left-hand side will get evaluated before the right-hand side. Also, yes, if the left-hand side is false/true (for &&/||), the right-hand side is not evaluated.
What does the standard say about evaluating && expressions - does it guarantee that evaluation of parameters will stop at the first false?
Also, is the order of evaluation guaranteed to be the order of appearence in the clause?
5.14/1. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
This only works for the standard && operator, user defined overloads of operator && don't have this guarantee, they behave like regular function call semantics.
Might the optimizer change something like:
if ( p->doSomethingReallyExpensive() && x == 3 )
to a form where it evaluates x==3 first?
An optimizer may decide to evaluate x == 3 first since it is an expression with no side-effects associated if x is not modified by p->doSomethingReallyExpensive(), or even evaluate it after p->doSomethingReallyExpensive() already returned false. However, the visible behavior is guaranteed to be the previously specified: Left to right evaluation and short-circuit. That means that while x == 3 may be evaluated first and return false the implementation still has to evaluate p->doSomethingReallyExpensive().
I recently came across something that I thought I understood right off the bat, but thinking more on it I would like understanding on why it works the way it does.
Consider the code below. The (x-- == 9) is clearly getting evaluated, while the (y++ == 11) is not. My first thought was that logical && kicks in, sees that the expression has already become false, and kicks out before evaluating the second part of the expression.
The more I think about it, the more I don't understand why this behaves as it does. As I understand it, logical operators fall below increment operations in the order of precedence. Shouldn't (y++ == 11) be evaluated, even though the overall expression has already become false?
In other words, shouldn't the order of operations dictate that (y++ == 11) be evaluated before the if statement realizes the expression as a whole will be false?
#include <iostream>
using namespace std;
int main( int argc, char** argv )
{
int x = 10;
int y = 10;
if( (x-- == 9) && (y++ == 11) )
{
cout << "I better not get here!" << endl;
}
cout << "Final X: " << x << endl;
cout << "Final Y: " << y << endl;
return 0;
}
Output:
Final X: 9
Final Y: 10
logical operators fall below increment operations in the order of
precedence.
Order of precedence is not order of execution. They're completely different concepts. Order of precedence only affects order of execution to the extent that operands are evaluated before their operator, and order of precedence helps tell you what the operands are of each operator.
Short-circuiting operators are a partial exception even to the rule that operands are evaluated before the operator, since they evaluate the LHS, then the operator has its say whether or not to evaluate the RHS, maybe the RHS is evaluated, then the result of the operator is computed.
Do not think of higher-precedence operations "executing first". Think of them "binding tighter". ++ has higher precedence than &&, and in the expression x ++ && y ++, operator precedence means that the ++ "binds more tightly" to y than && does, and so the expression overall is equivalent to (x++) && (y++), not (x++ && y) ++.
Shouldn't (y++ == 11) be evaluated, even though the overall expression has already become false?
No: the && and || operators short-circuit: they are evaluated left-to-right and as soon as the result of the expression is known, evaluation stops (that is, as soon as the expression is known to be false in the case of a series of &&, or true in the case of a series of ||)(*).
There is no sense in doing extra work that doesn't need to be done. This short-circuiting behavior is also quite useful and enables the writing of terser code. For example, given a pointer to a struct-type object, you can test whether the pointer is null and then dereference the pointer in a subsequent subexpression, for example: if (p && p->is_set) { /* ... */ }.
(*) Note that in C++, you can overload both the && and the || for class-type operands and if you do, they lose their short-circuiting property (it is generally inadvisable to overload && and || for this reason).
Precedence and associativity do not specify the order in which the operations are actually performed. They specify how operations are grouped: that is, in the following expression:
x && y++
...the lower precedence of && says that it is grouped as if it was:
x && (y++)
rather than as
(x && y)++
In your expression, the relative precedence of && and ++ do not matter, because you have separated those operators with parentheses anyway.
Grouping (and therefore precedence and associativity) specify what value each operator is operating on; but it specifies nothing about when it does so.
For most operators, the order in which the operations are performed is unspecified - however, in the case of && it is specified to evaluate the left hand operand first, then only evaluate the right hand operand if the result of the left hand operand was non-zero.
No. Order of precedence simply decides whether you get this:
A && B
(with A being x-- == 9 and B being y++ == 11) or
A == B == C
(with A being x--, B being 9 && y++, and C being 11).
Obviously, we're dealing with the first case. Short circuiting fully applies; if A is true, then B is not evaluated.
The conditional operators evaluate left-to-right and stop as soon as the result is known (an AND with a falsity or an OR with a true value).
C standard does not dictate any particular order of expression evaluation in if. So behavior will be compiler specific and using this style of coding not portable. You face that problem because incrementing/decrementing of value is post operation, but standard says as post operation of expression where variable is used. So if a compiler considers that your expression is just single variable usage as x or y, then you will see one result. If a compiler thinks that expression is entire if expression evaluation, then you will see other result. I hope it helps.