# Operator Precedence?

Show 80 post(s) from this thread on one page
Page 1 of 4 1234 Last
• 05-02-2008
cpjust
Operator Precedence?
I just noticed something a bit strange at the bottom of this page:
http://www.cppreference.com/operator_precedence.html

For this code:
Code:

```float x = 1; x = x / ++x;```
It says:
Quote:

The value of x is not guaranteed to be consistent across different compilers, because it is not clear whether the computer should evaluate the left or the right side of the division first. Depending on which side is evaluated first, x could take a different value.
But the ++ pre-increment operator is 2 levels above the / division operator, so I don't see why there would be any confusion about what to do first?
Is that page incorrect? If not, how can it be true?
• 05-02-2008
tabstop
Yes, but when should the compiler grab the value of x to use on the left side of the division: before anything happens, or just when it is needed? You don't know, and I don't know.
• 05-02-2008
swoopy
>because it is not clear whether the computer should evaluate the left or the right side of the division first.
So is the x on the left side of the division the original x, or the new x? The following suffers from the same ambiguity:
Code:

```float x = 1; x = x / x++;```
• 05-02-2008
brewbuck
Quote:

Originally Posted by cpjust
But the ++ pre-increment operator is 2 levels above the / division operator, so I don't see why there would be any confusion about what to do first?
Is that page incorrect? If not, how can it be true?

The relative precedence of the operators has nothing to do with it. Precedence only comes into play when there is an ambiguity about which operator should be applied first -- in other words, which expression the operator binds to most tightly. There is no ambiguity here in that regard. The preincrement operator clearly must bind to 'x' and nothing else.

What is ambiguous is whether the left side or the right side of the division expression will be evaluated first.
• 05-02-2008
cpjust
Quote:

Originally Posted by brewbuck
The relative precedence of the operators has nothing to do with it. Precedence only comes into play when there is an ambiguity about which operator should be applied first -- in other words, which expression the operator binds to most tightly. There is no ambiguity here in that regard. The preincrement operator clearly must bind to 'x' and nothing else.

What is ambiguous is whether the left side or the right side of the division expression will be evaluated first.

I thought it would have done it in steps:
First do ++x
Then do x / x

If I was writing a compiler, I'm sure that's how I'd make it work.

And since ++ happens before /, I don't see the problem.
x was 0, then it gets incremented to 1, so you have 1 / 1.
The compiler can't see it as 0 / 0 because ++ has a higher precedence, and it would never see it as 0 / 1 would it?
• 05-02-2008
brewbuck
Quote:

Originally Posted by cpjust
I thought it would have done it in steps:
First do ++x
Then do x / x

What's so special about the right hand side -- why should it get evaluated first?

Quote:

If I was writing a compiler, I'm sure that's how I'd make it work.
The order of evaluation of subexpressions was deliberately left unspecified so that compilers could actually optimize stuff.

Quote:

And since ++ happens before /, I don't see the problem.
Why do you think the ++ happens before / ? The order of evaluation is unspecified.

Quote:

The compiler can't see it as 0 / 0 because ++ has a higher precedence, and it would never see it as 0 / 1 would it?
Again, precedence has absolutely nothing to do with this. If the precedence of / and ++ were reversed the exact same ambiguity would remain.
• 05-02-2008
phantomotap
Quote:

The compiler can't see it as 0 / 0 because ++ has a higher precedence, and it would never see it as 0 / 1 would it?
Actually, I know a few compilers that will see it as "0/0" with optimizations turned on, but it's unusual for a compiler to try that. Anyway, it depends on how the compiler was designed.

The compiler might see this source as:

Code:

```++x; x /= x;```
or

Code:

```y = x; ++x; y /= x;```
Soma
• 05-02-2008
cpjust
Quote:

Originally Posted by brewbuck
The order of evaluation of subexpressions was deliberately left unspecified so that compilers could actually optimize stuff.

OK, maybe I'm not understanding the point of the Order of Evaluation correctly, but I thought it was the same as the order of operations that they teach us in math class.
i.e. 2*4+5/2-6*9 = (2*4) + (5/2) - (6*9) instead of 2 * (4+5) / (2-6) * 9 or anything in between.

Quote:

Originally Posted by brewbuck
Why do you think the ++ happens before / ? The order of evaluation is unspecified.

A higher precedence means that operation will be evaluated before ones with a lower precedence, right? So how can it be unspecified if ++ is 2 levels higher than /
• 05-02-2008
tabstop
This has nothing to do with order of operations[*] and everything to do with the fact that you have the same letter in two different places. If it was y/++x, everything would be completely spiffy. But you have x/++x. Does the first x refer to the x we had when we started, or the x we get after incrementing? Yes, ++ happens before /, but that has nothing to do with the problem -- why should what appears on the right side of the division sign affect what appears on the left side of the division sign? The view of the standard is that there is no legitimate use of the expression "x/++x" and consequently the compiler can do whatever it wants.
• 05-02-2008
brewbuck
Quote:

Originally Posted by cpjust
OK, maybe I'm not understanding the point of the Order of Evaluation correctly, but I thought it was the same as the order of operations that they teach us in math class.
i.e. 2*4+5/2-6*9 = (2*4) + (5/2) - (6*9) instead of 2 * (4+5) / (2-6) * 9 or anything in between.

That's not the question. The question is, do you evaluate the (4+5) first, or the (6*9)? Clearly it doesn't matter, since the result does not depend on that.

Maybe a very simple example will help.

Code:

`foo() + bar();`
Will foo() get called first, or bar()? It is unspecified. There is no issue of precedence, since only a single operator is involved here.

Quote:

A higher precedence means that operation will be evaluated before ones with a lower precedence, right? So how can it be unspecified if ++ is 2 levels higher than /
Precedence has nothing to do with order of evaluation. It has to do with how the operators bind to operands.
• 05-02-2008
brewbuck
Quote:

Originally Posted by tabstop
This has nothing to do with order of evaluation and everything to do with the fact that you have the same letter in two different places.

No, it is the reuse of the same variable which causes the order of evaluation to start making a difference, whereas in most other situations it would not matter.
• 05-02-2008
tabstop
Quote:

Originally Posted by brewbuck
No, it is the reuse of the same variable which causes the order of evaluation to start making a difference, whereas in most other situations it would not matter.

Yes, that's right. I meant order of operations and will edit to reflect that.
• 05-02-2008
Dave_Sinkula
• 05-02-2008
iMalc
Perhaps this will explain it better. Take a look at the following line:
Code:

`result = a() * b() + c() * d();`
Precedence rules tell us that the parse tree looks like this:
Code:

```        +       /    \     *        *   /  \    /  \ a()  b() c()  d()```
```    *   /  \ a()    +       /  \     b()    *         /  \       c()  d()```