In the following code,
int main() {
int a =1, b = 2, c = 3;
if(((a++) == 5) && ((b++) == 5) && ((c++) == 5)) {
cout<<"inside if"<< endl; // prints !!!Hello World!!!
}
cout<<a<<b<<c<<endl;
return 0;
}
all increment operation should be done before doing logical operation. But execution skips increment b and c. Why logical && precede over ()? By the way, result of this code is 223.
Because of short circuiting: when the left hand side of && is false, the right-hand side is not evaluated. The precedence, on the other hand, is the way you think it should be (and, as AnT says, it's unrelated to the behavior you're seeing): () has precedence over &&.
(Similarly, when the left hand side of || is true, the right-hand side is not evaluated.)
all increment operation should be done before doing logical operation
This is simply not true. There's no reason why increment operation should be done before doing logical operation and () does not change that in any way. As it has been stated many times before, operator precedence does not have anything to do with order of evaluation. These are two completely unrelated concepts.
At the top level, your expression has the following structure
<term1> && <term2> && <term3> && ... && <termN>
Such expressions are always evaluated in strictly sequenced left-to-right order from <term1> to <termN> (with possibly short-circuited evaluation). It is completely irrelevant what you have inside those terms: nothing inside <term2> will ever be evaluated before <term1>.
Related
Let's say I have a vector of unknown length.
I want to check if there is a value at vector[3] that is equal to x.
I have to first check if the vector has a length of at least 4.
if(vector.length()>=4)
{
if(vector.at(3) == x)
// Do something
}
My question is: Is it correct to write the same code like this:
if(vector.length()>=4 && vector.at(3) == x)
// Do something
?
Yes, these are equivalent.
The logical AND operator && has what is referred to as short circuit behavior. If the left operand evaluates to false (i.e. 0) then the entire expression is false and the right operand is not evaluated.
I've been familiar with the ternary operator for quite some time now, and have worked with it in a few differnet languages. My understanding of the operator is this:
condition ? expr1 : expr2
However, in C++, the following code is legal:
int i = 45;
(i > 0) ? i-- : 1;
Aren't you, in effect, just writing 1; or i - 1;How is this a complete statement? I understand that the intention of the code is to decrement i if it's greater than 0, but I would've thought that the code would generate a compiler error as just being an expression, not a full statement. I expected code like this:
int i = 45;
i = (i > 0) ? i - 1 : i;
This is called expression statement. The expression is evaluated and its value is discarded.
Even this is valid:
42;
although it does nothing. Only side effects (like i--, assignment, etc) in the expression have effects.
In fact, many statements we use are expression statements: assignments, function calls, etc:
a = 42;
foo();
That is a valid expression. You might have received a warning because you are not saving the result of the expression, but that you have the i-- your statement does have an effect.
In C++, an expression like 1 is a perfectly valid statement with no side effects. You could very feasibly write this function:
void f() {
1;
}
In fact, even this is correct.
void f() {
;;;;
}
A literal statement evaluates its arguments but does nothing more. The system views 1; as being just like func();. The only difference is that while func(); would logically have some side effects, 1; does not so it ends up being a no-op. The ternary operator evaluates like an if-statement, so the second form is only evaluated if the operand is true. Thus:
(i > 0) ? i-- : 1;
If i is greater than 0, the second form is evaluated. When it is evaluated, it carries its side effect, which decrements i by 1. Otherwise, the third form is evaluated, which does nothing. Although this block of code works, it is not incredibly readable, so while it's nice toy code a real if-statement is ideal for situations like this. For the same reason, this line would have the same effect but be frowned upon for being equally unreadable.
((i > 0) && (i--)) || 1;
Assuming you didn't overwrite the boolean operators, this code will short-circuit and behave like the ternary operator. If i is not greater than 0, then the && need not evaluate its second operand since the && is false, but the || must since it might be true. Inversely, if i is greater than 0, the && needs to evaluate but the || already knows it's true.
Aren't you, in effect, just writing 1; or i - 1;
No: i-- is not the same as i - 1. In the first case, the value of i is modified. In the second case it is not.
In the event that i less than or equal to zero, then you're correct that the resulting 'code' will be 1. However, the compiler will realise that this is not a useful thing to execute and so it ought to generate code equivalent to:
if( i > 0 ) i--;
Some (including myself) would consider that using the ternary operator in this fashion is bad style. Just for fun, here's another way someone might write it that's also not very nice (also more likely to generate compiler warning):
i > 0 && i--;
In the end, style is a matter of preference. The compiler, for the most part, will decide the best way to turn your code into assembly. So you owe it to yourself to write code that is clear and concise.
I just saw the code and I am unable to understand how the logical and behaves with "cout" here:
int userInput = 9; // Suppose user input is 9.
int remainder = 9 % 2;
(remainder & 1 && std::cout<<"odd" )|| cout<<"even";
std::cout<<"odd" is an expression that will return std::cout (which is why you can do std::cout << a << b << c). When evaluated in boolean context, it simply returns true if the fail bit isn't set. So if the output operation succeeds then it will evaluate as true.
However, the intent of this code isn't to test that value, rather it is a clever (and not very readable)1 way to express this:
if (remainder & 1) {
std::cout << "odd";
} else {
std::cout << "even";
}
It takes advantage of the short-circuiting nature of the && and || operators:
In a && b, if a is false then it evaluates as a (b is not evaluated!) otherwise it evaluates as b.
In a || b, if a is true then it evaluates as a (b is not evaluated!) otherwise it evaluates as b.
So if remainder & 1 evaluates as false (zero in this case) then std::cout << "odd" is not evaluated because the && expression short-circuits, returning false. This is the left operand to the outer || expression, which causes its b (std::cout << "even") to be evaluated, writing "even" to the output.
If remainder & 1 evaluates as true (non-zero in this case) then the right operand for && is evaluated, displaying "odd". Assuming that this operation succeeds, the left operand for the || operation will be true, which causes it to short-circuit and not evaluate the right operand.
1 Experienced programmers are likely to know exactly what is going on here, but as you have found this technique is not the most readable. It's better (IMO) to be straightforward about the intent of code, so I would just use an if conditional -- or, at the very least, use the ternary operator: std::cout << (remainder & 1 ? "odd" : "even").
In other languages (JavaScript comes to mind) (ab)using the short-circuiting operators is a very common technique. I usually don't see them used this way in C++ and I would strongly discourage such use.
The line in question:
(remainder & 1 && std::cout<<"odd" ) || cout<<"even";
Is the same as the following when you take operator precedence and operator overloads into account:
((remainder & 1) && (operator<<(std::cout, "odd").operator bool())) || (operator<<(std::cout, "even").operator bool());
std::cout (more generically, std::basic_ostream) has operator<<() and operator bool() operators defined. The first operator returns a std::basic_ostream& reference, ie a reference to the stream itself (useful for chaining operations together). The second operator returns whether the stream is in a failure state or not.
See the following documentation for more details:
C++ operator precedence
operator overloading
std::basic_ostream::operator<<
std::basic_ios::operator bool
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Logical comparisons: Is left-to-right evaluation guaranteed?
I have been taught that for every C function arguments, Rightmost argument will be executed/processed first and it progresses towards left.
Right part will be executed first and it progresses towards left.
Is this applicable to conditions like && and || ??
If I am writing a C++ Code, I check for NULL condtion first and then in next if I perform my action. for e.g.
if( CommDevice != NULL)
{
if(CommDevice->isOpen == TRUE)
{
//Do Something
}
}
Can I convert this in if((CommDevice != NULL) && (CommDevice->isOpen == TRUE) )
That "Code executes from Right to Left" fear is stopping me coz what if CommDevice is NULL and I am trying to access a member of NULL. It will generate exception.
I have been taught that every C function takes argument from right to left. Right part will be executed first and it progresses towards left.
This is 100% not true. The order of argument evaluation is unspecified!
The order of && and || is defined because it forms a sequence point. First the left is evaluated, and if not short-circuiting then the right is evaluated.
if((CommDevice != NULL) && (CommDevice->isOpen == TRUE) )
This is correct.
From the "C Programming Language" by Brian Kernighan & Ritchie Dennis (authors of C):
"Expressions connected by && or || are evaluated left to right, and it is guaranteed that evaluation will stop as soon as the truth or falsehood is known."
I should point out that I once confused the order of evaluation rules for && and || with the following in C:
x = f() + g();
Note that order of evaluation for f() vs. g() CANNOT be determined.
&& evaluates from left to right, not right to left! So your code will NOT throw any exception.
Order of evaluation of functions arguments is Unspecified .So whatever you have been taught is not according to language standard.
Regarding your code :
The order of evaluation of && and || is specified and this is Left to right
And this also follows the short-circuit of statement
In case of && if 1st is false then rest of the conditions will not be executed.
Similar in || if 1st is true then rest of the conditions will not be executed.
And also && and || are sequence points.
As far as the logical operators are concerned, you're touching on short-circuit evaluation.
It is safe to check for the NULL pointer first on the left, because if this condition returns false, then the next condition of the && (from left to right) is not evaluated.
This behavior is allowed because of the basic logical principles of && and ||.
The program is as
main()
{
int a=1;
if( a-- > 0)
printf("AAAA");
else
printf("BBBB");
}
Its output is AAAA
and if I use
main()
{
int a=1;
if( (a--) > 0)
printf("AAAA");
else
printf("BBBB");
}
then why again the output is AAAA.
() has more preference then -- .
The postfix operator -- has higher precedence than any boolean comparison operator.
What do you expect exactly? a-- always evaluates to the value of a which is decremented after evaluation.
The postfix -- operator returns the original value of the variable, even after decrementing it.
So yes, a is decremented before the comparison, but the result of the expression a-- is not a, but the value 1.
-- decrements the value of a variable after it is used in the expression.
The use of parentheses here doesn't have any effect on the code because the order of evaluation is the same with and without the parentheses. You are correct that parentheses have higher precedence than --. However, in this case the parentheses won't change the order of evaluation because you didn't group the operands in a different order than they'd evaluate naturally.
Here is a link with all the operator's precedence in C++.