Is if statement order check fr object depend on compiler? [duplicate] - c++

This question already has an answer here:
Logical AND, OR: Is left-to-right evaluation guaranteed?
(1 answer)
Closed 5 years ago.
Quick question. How the following code will perform order of check :
if ((NULL != ObjectPtr) && (ObjectPtr->isValid()) )
{
}
Is the order on if-statement depend on compiler used? Could that code crash if ObjectPtr is NULL?

Is the order depend on if statement depend on compiler used?
No.
Could that code crash if ObjectPtr is NULL?
No.
The language guarantees that.

In C++, the && operator is guaranteed to be short-circuiting. This means that the left-hand operand is checked first, and if it is false, none of the right-hand operand is evaluated.
So your code is safe and will not perform member access through the NULL pointer.
Similarly, || is also short-circuiting and will not evaluate any of its right-hand operand if the left operand is true.
With boolean operands, the bitwise operators & and | give the same result as the logical operators && and ||, but the bitwise operators do not short-circuit and their right-hand operand is always evaluated (possibly before the left-hand one).
Also as Quentin mentions in a comment, user-provided overloads of these operators do not short-circuit, because they are actually function calls and have the evaluation order of function calls (all arguments evaluated before the call).

Related

Does anyone know about the implementation of || and && regarding this code? [duplicate]

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)

OR Statement performing all evaluations [duplicate]

This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 3 years ago.
In an OR evaluation does C++ continue evaluating past the first TRUE it finds?
ie.
if(Foo() || Bar())
{
//..
}
If Foo() returns true will Bar() be skipped completely or will it also run that function?
Operators && and || perform so called short-circuit evaluation, which means they do not evaluate the second operand if the result is known after evaluating the first. So no, Bar() would not be evaluated in this case.
EDIT: That's the built-in functionality, as other people said. If they are overloaded, you obviously can't rely on it anymore.
The built-in || operator short-circuits. The left-hand expression is guaranteed to be evaluated first, and if the result is true, the right-hand expression is not evaluated.
The && operator is the opposite. The left-hand expression is evaluated first and if it evaluates to false then the right-hand expression is not evaluated.
Note that this does not hold for user-defined operator|| and operator&& overloads. Those do not provide short-circuit evaluation. Both sides of the expression will be evaluated.

Is an if statement guaranteed to not be evaluated more than necessary? [duplicate]

This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
How does C++ handle &&? (Short-circuit evaluation) [duplicate]
(7 answers)
Closed 9 years ago.
Given two conditions with an && connection. I know that the order of evaluation is from left to right. But if the first condition resolves to false, it the second condition guaranteed to not get evaluated?
#define SIZE
bool array[SIZE];
int index;
// play with variables
// ...
if(index < SIZE && array[index])
{
// ...
}
In this example, if the first condition is false the second must not be evaluated since the access in the array would be out of range.
By the way I cannot simply nest the conditionals with two if statements, since actually I need the inverse like (!(in_range && get_element)). With nested statements I would need to use goto to jump over the code block below that.
But if the first condition resolves to false, it the second condition guaranteed to not get evaluated?
Yes, that's C++'s short circuiting. Per paragraph 5.14/1 of the C++11 Standard:
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.
As MatthieuM. correctly mentions in the comments, the above applies only to the built-in logical AND and logical OR operators: if those operators are overloaded, invoking them is treated as a regular function call (so no short-circuiting applies and no order of evaluation is guaranteed).
As specified in paragraph 5/2:
[Note: Operators can be overloaded, that is, given meaning when applied to expressions of class type (Clause
9) or enumeration type (7.2). Uses of overloaded operators are transformed into function calls as described
in 13.5. Overloaded operators obey the rules for syntax specified in Clause 5, but the requirements of
operand type, value category, and evaluation order are replaced by the rules for function call. [...] —end note ]

C++ 'AND' evaluation - standard guaranteed? [duplicate]

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().

What is the order of evaluating boolean sentence? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Is short-circuiting boolean operators mandated in C/C++? And evaluation order?
Is there any defined by standard or math rules order of eveluating boolean sentences? For example:
if (firstTrue && secondTrue)
{
}
can I be sure that firstTrue will be checked first?
Yes. && and || are short circuiting operators. The order of evaluation of operands is well defined (left to right).
&& is also a sequence point.
So writing if( ++i && i) { } is perfectly fine.
ISO C++03 (5.14/1) says:
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.
EDIT: (After seeing the comment)
ISO C++03 (Section 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.
Yes firstTrue will be evaluated first. In fact, if firstTrue is false, the secondTrue will not even be evaluated. This is called short circuiting.
Check out this article: http://en.wikipedia.org/wiki/Short-circuit_evaluation
The same happens with ||. If the first argument to || is true, the second will not be evaluated.
It is not about boolean sentences. It is about specific operators in these "sentences" (logical expressions, actually)
The built-in && operator (as well as ||) are special: they guarantee that the left-hand side is evaluated before the right-hand size. They have a sequence point between the LHS and RHS evaluations. And they don't evaluate the RHS if the result is pre-determined by the LHS. Aside from this (and some other operators that have similar sequencing properties), there are no guarantees about the order of evaluation of logical expressions, or any other expressions.
The above applies to built-in && and || operators. Overloaded && and || operators are not special in any way.