Ok, I'm wondering what this will do.
Will the actions execute? Does c++ consider ands before ors, or vice versa?Code:int x=1, b=2;
if(x == 1 && b == 2 || x == 2 && b == 2) {
//actions;
}
Printable View
Ok, I'm wondering what this will do.
Will the actions execute? Does c++ consider ands before ors, or vice versa?Code:int x=1, b=2;
if(x == 1 && b == 2 || x == 2 && b == 2) {
//actions;
}
&& are evaluated before || , in this case actions will exec.
&& will exec when both expressions are true, but || will exec when 1 of the expressions is true.
Actually, I dont see why you cant work it out yourself.
The expression boils down to:
true && true || false && true
which is:
true || false && true
Suppose that we keep left to right evaluation, this means that we get:
true && true
which of course evaluates to true
Suppose we decide to evaluate the logical AND expression first, we get:
true || false
which of course evaluates to true
In fact, I think the C++ standard doesnt actually specify the precedence, but notes that the precedence comes from the syntax. Due to lazy evaluation I think the (x == 2 && b == 2) expression isnt evaluated at all, since the true as the left hand side of the logical OR is sufficient to determine that the entire expression evaluates to true.
That said, just group your expressions with parentheses if you want to avoid this sort of confusion.
Which is:
((x == 1) && (b == 2)) || ((x == 2) && (b == 2))
((1 == 1) && (2 == 2)) || ((1 == 2) && (2 == 2))
(1 && 1) || (0 && 1)
1 || 0
1
I use parenthesis even if they have precedence, just to be clear, and so it doesn't even matter what the precedence is.
That is what happens, but I think it's better called short-circuiting evaluation than lazy evaluation, which means something similar but somewhat more insane in languages like Haskell.Quote:
Originally Posted by laserlight
Well, I was wondering because of this statement:
And I was wondering how the compiler saw that. Is it saying if x equals one or does x equal one and b equals two and c equal two. Or does x equal one or x equals one and b equals two or b equals two and c equals two.Code:if(x==1 || x==1 &&b==2 &&c==2)
But I guess the second one would be
So I'm guessing the double ampersand is taken into consideration before double lines.Code:if(x==1 || x==1 && b==2 || b==2 && c==2)
Thanks.
In my book's precedence tables, && has higher precedence than ||, and I think precedence has to be established to get predictable behavior.Quote:
In fact, I think the C++ standard doesnt actually specify the precedence
Easily tested:Quote:
Due to lazy evaluation I think the (x == 2 && b == 2) expression isnt evaluated at all, since the true as the left hand side of the logical OR is sufficient to determine that the entire expression evaluates to true.
Set x equal to 2 and run it again.Code:int x=1, b=2;
if(x == 1 && b == 2 || (x = 4) && (b = 4))
{
cout<<"x: "<<x<<endl;
cout<<"b: "<<b<<endl;
}
Since && has higher precedence than || as well as left associativity, that conditional is equivalent to:Quote:
Well, I was wondering because of this statement:
Code:if(x==1 || x==1 &&b==2 &&c==2)
x==1 || ( (x==1 &&b==2) &&c==2 )
So, if x==1 is true, the whole conditional is true, and therefore the compiler doesn't need to evaluate anything on the right side of the ||, i.e. it employs 'lazy evaluation' or 'short circuit' behavior. If x==1 is false, then evaluation has to move to the right of the || to determine whether the whole conditional is true or false. Since x==1 has to be false to move to the right of the ||, and the first thing evaluated on the right is x==1, we know that conditional has to be false. As a result, none of the other conditionals on the right need to be evaluated because all the logical operators are &&'s, and since they are being &&'ed together with something that is false, they have to be false. Therefore, nothing to the right of the first && will ever be evaluated.
You can prove that to yourself by changing some of the conditionals to assignment statements(remember 0 evaluates to false and anything else evaluates to true), and playing with the initial values of x, b, c and then displaying x, b, and c to see which assignments inside the conditional were executed.
hmm... I decided to look it up, and from section 5 of the C++ Standard:Quote:
In my book's precedence tables, && has higher precedence than ||, and I think precedence has to be established to get predictable behavior.
"Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified."
At the end of that is a superscript leading to a note which reads:
"The precedence of operators is not directly specified, but it can be derived from the syntax."
Going down to the individual paragraphs, logical AND is given as:
logical-and-expression:
inclusive-or-expression
logical-and-expression && inclusive-or-expression
while logical OR is given as:
logical-or-expression:
logical-and-expression
logical-or-expression || logical-and-expression
That a logical-or-expression is defined in terms of a logical-and-expression which is in turn defined in terms of an inclusive-or-expression means that we can conclude that && has a higher precedence than ||
I suppose that is what the standard means by the precedence being derived from the syntax rather than being listed in some precedence table, which I couldnt find.
I've always assumed there would be a precedence table though, since every introductory text on the topic I've seen listed it as such - but then it makes sense to simplify the list outright so that it is easier to digest and remember.
GCC gives you a warning with this code:
Something like "suggest parenthesis around &&".Code:if(x == 1 && y == 1 || z == 1)