# Thread: Operator Precedence?

1. ## 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:
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?

2. 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.

3. >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++;```

4. 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.

5. 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?

6. 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?

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.

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

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.

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

8. 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.

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 /

9. 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.

10. 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.

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.

11. 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.

12. 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.

13. 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()```
instead of for example this:
Code:
```    *
/   \
a()     +
/   \
b()    *
/   \
c()   d()```
However you don't know what order a(), b(), c() and d() will be called. That's evaluation, not precedence.
It could call c() then d(), then do the second *, then call a, then b, then do the first *, then do the +. If the functions a, b, c, and d all make certain modifications to a global variable and then return the current value of that global variable for example, then different evaluation orders would produce different results.

However, no compiler would be allowed to generate the second parse tree I showed as it has incorrect precedence rules applied to it. Only using brackets could allow such a parse tree to result.

14. >If it was y/++x, everything would be completely spiffy.
That would be undefined as well if there's an x left of the assignment operator.

Popular pages Recent additions