Win a copy of Functional Reactive Programming this week in the Other Languages forum!

# yet another postfix/prefix precedence question

Greg Stevens
Ranch Hand
Posts: 41
While trying to make sense of postfix/prefix precedence, I came across http://www.coderanch.com/t/411365/Beginning-Java/java/Post-increment-Pre-Increment-Precedence#1811178 thread.

The poster poses this problem:

i=10
a = i++ + ++i + i--;

Following the rule that postfix increment has highest precedence, the poster thinks the expression should
evaluate to 32.

EFH works through the evaluation using left-to-right (first term, second term, third term) to get 34, which is
what the compiler computes.

I ran this code:

This is the output:

The thread ends with that. I'm confused. I can follow the left-to-right evaluation, that's fine. But if the rule
is that postfix has higher precedence, why doesn't it apply here? And if it doesn't apply here, what is an
example that does demonstrates postfix's precedence being higher than prefix's? And, of course, if
it doesn't apply here, but does apply in other cases, why the apparent contradiction?

Rajeev Trikha
Ranch Hand
Posts: 85
Use this to clarify ideas

int i = 10;
int a, b, c, d;
a = (b = i++) + (c = ++i) + (d = i--);
System.out.println(a + " " + i + " " + b + " " + c + " " + d);

which shows how the output 34 11 10 12 12 was created.

Similarly if we replace with the code

int i = 10;
int a, b, c, d;
a = (b = ++i) + (c = ++i) + (d = i--);
System.out.println(a + " " + i + " " + b + " " + c + " " + d);

we get 35 11 11 12 12

Greg Stevens
Ranch Hand
Posts: 41
In both of the examples the terms are simplified from left to right. The rightmost postfix operator is not applied before the middle prefix operator.
What is the point of saying postfix has higher precedence than prefix if it doesn't get evaluated first?

int i = 10;
int a, b, c, d;
a = (b = i++) + (c = ++i) + (d = i--);

if postfix evaluates first shouldn't we get

b = 10, i = 11
d = 11, i = 10
+ c = 11, i = 11
----------
a = 32

Campbell Ritchie
Sheriff
Posts: 50248
79
No, you are both in this thread and your other thread, confusing the ++ operator and the i++ expression.

You are working from left to right and each operator is evaluated in orderEasy. Only one operator. Value of i: 10You need to take it is bits,and you need to understand that i and i++ have different values.
I shall take that statement apart and look at the order the operators are evaluated in.The = operator has the lowest precedence of all, so it waits until whatever is on its right is evaluated first.The postfix ++ operator has the highest precedence of all, so it is evaluated first. The value of i is now 11 and the value of i++ is the old value, ie 10.The + has a higher precedence operator on its right, so it waits until that is executed.The value of i and ++i are both 12.This operator has a lower precedence than the + on its left, because + is a left-associative operator. So we now have22.

Back to the right-hand +. On its right there is a higher-precedence operator, so that is executed firstThe value of i is 11, but the value of the whole expression i-- is 12. So we now havewhich makes 34. You can easily work out the rest for yourself.

Greg Stevens
Ranch Hand
Posts: 41
I'm still confused. I've been trying to figure this out all day. I think I'll just have to let it go for a while. It just makes no sense whatsoever to me to
say post increment operator has highest precedence post decrement operator has higher precedence than pre increment operator, but
pre increment is evaluated first. Obviously I am confused about the meaning of precedence. Common usage of precedence refers to one thing happening
before another. How can something that happens first happen last?

Campbell Ritchie
Sheriff
Posts: 50248
79
It's not just a case of the higher precedence operations being evaluated first, but the lower precedence operations being executed last. And you go from left to right. Once a value has been evaluated to the left of an operator, it is not changed.
The first i++ is evaluated first, then the left-hand +, but that requires the ++i precede it.

Did you read the Java™ Language Specification section I quoted here? More to the point: did you understand any of it ?

Henry Wong
author
Marshal
Posts: 21506
84
Greg Stevens wrote:I'm still confused. It just makes no sense whatsoever to me to say post increment operator has highest precedence post decrement operator has higher precedence than pre increment operator

It makes no sense because you can't apply the pre increment or the post increment more than once -- with an appearance of a variable. Or even apply them both like...

Both the pre increment and post increment operator can only be applied to a variable, and not to an expression, so you can't apply them both at the same time, and hence, there is no meaning in saying one has precedence over the other.

Not all things in the precedence table are comparable, sometimes they are listed where they are for other operators in the table.

Greg Stevens wrote:but pre increment is evaluated first. Obviously I am confused about the meaning of precedence. Common usage of precedence refers to one thing happening before another.

Woah!!! Stop!! Halt!!

Remember this. Precedence and Evaluation Order are two different things. Do not ever confuse the two. Unfortunately, your example doesn't demo this very well, so here is a different example. Take...

Precedence determines grouping. Since multiply has higher precedence than addition, which in turn, has higher precedence than an assignment, the expression is grouped as....

But Precedence is not the same thing as Evaluation Order!!! Evaluation order is determined by section 15.7 of the JLS, and for the most post is done left to right. So, for the expression... the compiler will start with "a", determine its an assignment, starts a subexpression because of "(", start with 4, add, subexpression because of "("... etc. etc. etc.

Henry

Greg Stevens
Ranch Hand
Posts: 41
• 1
Thanks for the patience guys. I think I am getting a little closer to understanding this.

Precedence has more to do with which operator is applied to an operand when it is shared by two operators. Precedence does not mean
order of evaluation (like order of evaluation in math).

So,

The higher precedence of ++ and -- compared to * means that they are each applied to their operands before *, which shares an operand
with each. There really is no meaning to saying postdecrement has higher precedence than preincrement because those two operators
would never share an operand?

And next example is the one I need to definitely be sure I understand, because this is how it is being presented in my class:

The instructor is saying x++ is evaluated first (like one would do with PEMDAS and exponents), giving 5 and changing x to 6, then the first x
evaluates to 6 and we have 6 + 5 == 11. He says it is a compiler error causing it to evaluate 10 and we will have "order of evaluation
problems" on our midterm and we need to know how to do them correctly, according to the "ANSI standard". I know this is wrong. I at least
want to make sure I understand them if I get them all wrong on the test.

But now I understand that the higher precedence of ++ above only means that x is incremented before the two operands of * are
multiplied. And according to JLS 15.7.1, the left operand of a binary operator is evaluated first. This is not in contradiction to the higher
precedence of ++ because ++ is applied to its operand before * is applied to its two operands.

Precedence and Evaluation Order are two different things. I feel much better now. The world is all well again -- as well as it was before
I freaked out anyway.

fred rosenberger
lowercase baba
Bartender
Posts: 12200
35
are you taking a java class or an ANSI class?

If it's a java class, I would argue that it doesn't matter what the ANSI standard is...you have to understand what Java does.

Granted, arguing with a professor is like yelling at the ocean. it won't do you any good, even if you are right.

Greg Stevens
Ranch Hand
Posts: 41
It is an introduction to object-oriented programming using Java class. The instructor clearly has operator precedence and
order of evaluation confused. I'm glad I came here, because even after reading the JLS, I knew something was wrong, but
not exactly what -- the specification is not very easy to decipher for mere mortals like myself. I would still be confused if
you guys hadn't told me operator precedence is not the same as order of evaluation.

Henry Wong
author
Marshal
Posts: 21506
84
Greg Stevens wrote:The instructor clearly has operator precedence and order of evaluation confused. I'm glad I came here, because even after reading the JLS, I knew something was wrong, but not exactly what -- the specification is not very easy to decipher for mere mortals like myself. I would still be confused if you guys hadn't told me operator precedence is not the same as order of evaluation.

It is really scary that there are many very senior programmers (and college professors) that don't understand the distinction between these two concepts. Especially, since it is not Java specific, and applies to most languages.

This is why I don't let precedence and /or order of evaluation to be in doubt. Always use parens. Try not to have a single expression that has side effects -- meaning embedded pre and post incrementors, decrementors, or even assignments. It is better to have many expressions that you (and others can understand), than to have a single more complex expression, that you, but maybe not your replacement, understands.

Henry

Campbell Ritchie
Sheriff
Posts: 50248
79
There is a point in having precedences for the ++ operators. Even though you can't use i++ and ++i together, there are other operators which can be used with them, for example (cast) and complement. I wrote a little class showing the complement operator (note I have OO on the brain so I even write my Helloworld classes with constructors Noting that ~10 == -11 and ~11 == -12, you can see which operators take precedence.

"What about ~++i?"I hear you say. Well, those operators associate to the right, so you regard the ++ as having slightly higher precedence than the ~. I think if you tried it the other way round (++~i), you would be applying a prefix increment operator to a number, and the compiler would throw an error.

Campbell Ritchie
Sheriff
Posts: 50248
79
By the way, what happens in Java if you write?And as Fred says, Java does not adhere to ANSI.

Greg Stevens
Ranch Hand
Posts: 41
Does this demonstrate that operator precedence is not the same thing as order of evaluation?

Any suggestions on how to make it cool and object-oriented like Campbell Ritchie's?

Campbell Ritchie
Sheriff
Posts: 50248
79
Now you can get rid of the static declarations.

Alternative technique:Put your text into String variables then you can print out the text with changes in a printMessage method.