Bit of confusion with if?

• 03-06-2006
Blackroot
Bit of confusion with if?
Ok, I'm wondering what this will do.

Code:

```int x=1, b=2; if(x == 1 && b == 2 || x == 2 && b == 2) {  //actions; }```
Will the actions execute? Does c++ consider ands before ors, or vice versa?
• 03-06-2006
InvariantLoop
&& 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.
• 03-06-2006
laserlight
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.
• 03-06-2006
Dae
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.
• 03-06-2006
Rashakil Fol
Quote:

Originally Posted by laserlight
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 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.
• 03-07-2006
Blackroot
Well, I was wondering because of this statement:

Code:

`if(x==1 || x==1 &&b==2 &&c==2)`
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.

But I guess the second one would be

Code:

`if(x==1 || x==1 && b==2 || b==2 && c==2)`
So I'm guessing the double ampersand is taken into consideration before double lines.

Thanks.
• 03-07-2006
7stud
Quote:

In fact, I think the C++ standard doesnt actually specify the precedence
In my book's precedence tables, && has higher precedence than ||, and I think precedence has to be established to get predictable behavior.

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.
Easily tested:
Code:

```int x=1, b=2; if(x == 1 && b == 2 || (x = 4) && (b = 4)) {         cout<<"x: "<<x<<endl;         cout<<"b: "<<b<<endl; }```
Set x equal to 2 and run it again.

Quote:

Well, I was wondering because of this statement:
Code:

`if(x==1 || x==1 &&b==2 &&c==2)`

Since && has higher precedence than || as well as left associativity, that conditional is equivalent to:

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.
• 03-07-2006
laserlight
Quote:

In my book's precedence tables, && has higher precedence than ||, and I think precedence has to be established to get predictable behavior.
hmm... I decided to look it up, and from section 5 of the C++ Standard:
"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.
• 03-07-2006
dwks
GCC gives you a warning with this code:
Code:

`if(x == 1 && y == 1 || z == 1)`
Something like "suggest parenthesis around &&".