• Post Reply Bookmark Topic Watch Topic
  • New Topic

Difference between y = ++x; and y = x++;  RSS feed

 
Robert Stepp
Greenhorn
Posts: 7
Chrome Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In Java: A Beginner's Guide, Sixth Edition by Herbert Schildt, page 48, the author gives the following code snippets:



Here x = 11 and y = 11.



Here x = 11 and y = 10.

I have run both code snippets to verify this behavior. What I don't understand is how this behavior fits in with operator precedence. According to the operator precedence table the assignment operator has much lower precedence than either the prefix or postfix forms of the increment operator. If this is true, it seems to me that y should be 11 in both examples. What am I not seeing here?
 
Skye Antinozzi
Ranch Hand
Posts: 68
3
Eclipse IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can read x++ as, "Use x, then increment it by 1." And inversely with ++x, "Increment x by one, then use x."

So when you have this snippet, using the pre-increment operator:



You are incrementing x by one and then assigning its value to y. So x will equal 11 and y will also equal 11.

In the other snippet, using the post-increment operator:



You are assigning the value of x to y and then incrementing x by one. So x will equal 11 and y will equal 10.

Two snippets can help show this fairly simply.



And also



In the first snippet x will print the value 10, then x will be incremented to 11.

In the second snippet x will increment to 11 and then be printed, outputting 11.

I hope you will see this more clearly now
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a slightly less clear way to look at that: x++ has a value and x has a value. But the two are not the same.

We have this sort of question quite frequently, and an FAQ about it.
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One way to understand this behaviour is when you consider sequence points and side effects...
 
Robert Stepp
Greenhorn
Posts: 7
Chrome Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, Skye, for your thoughtful response. I especially liked your clarifying println examples. Thanks, also to Campbell. BUT!

I must not have expressed myself clearly. The heart of my question was:

"According to the operator precedence table the assignment operator has much lower precedence than either the prefix or postfix forms of the increment operator. "

I understand (and had seen) the FAQ. I understand and accept Skye's points. But this behavior seems to violate the operator precedence hierarchy. The increment operators are at the very top with highest precedence, which, in my mind, means that their operations should occur first; whereas, the assignment operator is at the very bottom, which, again, seems to me should be applied last. So strictly in terms of operator precedence it seems that in both code snippets ++ should occur first and y = should occur last. I accept what actually happens, but I am currently unable to reconcile the actual behavior with the operator precedence concept. Have I clarified what I am really asking?
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Robert Stepp wrote:Thanks, Skye, for your thoughtful response. I especially liked your clarifying println examples. Thanks, also to Campbell. BUT!

I must not have expressed myself clearly. The heart of my question was:

"According to the operator precedence table the assignment operator has much lower precedence than either the prefix or postfix forms of the increment operator. "

And that is where Campbell's statement about the value of the expression comes in. The x++ expression has a value and a side effect. The operation occurs first, and its value is generated. Its value is the value of x before the increment. So that is what gets assigned to y. The operation's side effect is that x is incremented, but that doesn't come into play when determining the expression's value. Where as the ++x expression also has a value and a side effect. The operation occurs first and its value is generated. In this case the value is the value of x after the increment. So that is what is assigned to y.

edit: fixed an accidental bad word
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

In addition to what Steve stated, these statements ...

Robert Stepp wrote:
I must not have expressed myself clearly. The heart of my question was:

"According to the operator precedence table the assignment operator has much lower precedence than either the prefix or postfix forms of the increment operator. "

I understand (and had seen) the FAQ. I understand and accept Skye's points. But this behavior seems to violate the operator precedence hierarchy. The increment operators are at the very top with highest precedence, which, in my mind, means that their operations should occur first; whereas, the assignment operator is at the very bottom, which, again, seems to me should be applied last. So strictly in terms of operator precedence it seems that in both code snippets ++ should occur first and y = should occur last. I accept what actually happens, but I am currently unable to reconcile the actual behavior with the operator precedence concept. Have I clarified what I am really asking?


are also wrong. "Precedence" or "Order of Evaluation" are *not* the same thing. Higher precedence doesn't mean done first.

Henry
 
Robert Stepp
Greenhorn
Posts: 7
Chrome Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:
... "Precedence" or "Order of Evaluation" are *not* the same thing. Higher precedence doesn't mean done first.

Henry


I thought the whole point of "precedence" was to determine the proper order of operations? If this is not the case, what is really going on here? What is the point of establishing an order of precedence among operators?
 
Steve Fahlbusch
Bartender
Posts: 612
7
Mac OS X Python
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Greetings,

What is going on, goes back to the definition of these two different operators.

By defn: pre increment operator will increment the integer value and will evaluate to the updated value.

post increment operator will increment the integer value but will evaluate to the pre updated value.

and yes the ++ has a higher precedence than the =, and is evaluated prior to the assignment, but the two operators do different things.

HTH
-steve
 
Robert Stepp
Greenhorn
Posts: 7
Chrome Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


What is going on, goes back to the definition of these two different operators.

By defn: pre increment operator will increment the integer value and will evaluate to the updated value.

post increment operator will increment the integer value but will evaluate to the pre updated value.

and yes the ++ has a higher precedence than the =, and is evaluated prior to the assignment, but the two operators do different things.


This does make sense to me. The pre- and postfix versions of the ++ (and I presume -- is analagous) operators do execute before the assignment operator, but by their definitions evaluate to different results. I presume that the designers of Java had a good reason for these definitions? Something I will be more appreciative of in the future?

Many thanks!
 
Piet Souris
Master Rancher
Posts: 2041
75
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My advice: never ever use things like x++ in expressions.
It is asking for trouble.

Simply use:

x++;
y = x;

or

y = x;
x++;

Greetz,
Piet
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think the designers of Java defined the meanings of those operators as such, but just took them directly from C/C++. They were probably included to make it easier for programmers of those languages to switch to Java.

As a Java programmer I may occasionally use the post increment operator on one of the rare occasions I use a classic for-loop, simply because it is the standard idiom. I never use the pre-increment operator.
It may save a few lines of code using these operators in method calls and assignment statements, but the lack of clarity and maintainability isn't worth it in my opinion.

So don't worry too much about the, and as Piet says its often best to avoid using them altogether and be explicit about your intentions instead.
 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Robert Stepp wrote:
I thought the whole point of "precedence" was to determine the proper order of operations? If this is not the case, what is really going on here? What is the point of establishing an order of precedence among operators?


I'd suggest that start with the article shared by Campbell once more and read it several times till it starts making sense. The responses posted above also have a detailed explanation of the article.

You are basically having the same question that I had a few months back. And then I had chanced upon this article. This is with respect to C and C++. This gave me enough reasons to understand strictly in what contexts operators that induce a side effect could be used.

I had it in my list of things to do to check what the JLS says about them... It's still a pending thing I have in my list of things to do cause there are a lot of other more important things to be understood before.

Nevertheless, I think the article is a good read -- enough to understand what to avoid in what contexts.
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are places where it is correct coding to use i++ or i-- as parts of expressions, for example when assigning to array elements, but you need to be careful. So I shan't show any examples here. There are always different ways to do the same thing.

Yes, the operators were copied from C/C++, but their behaviour is not strictly defined in those languages. It is strictly defined in Java®.

Yes, the postfix operators have the highest precedence of anything in the table. That is why I said there is a value to the whole expression i++ and that is different from the value of i. I think Steve Luke has already explained it. I think you got it when you wrote
evaluate to different results
And yes, the behaviour of the −− operators is the same but with decreasing values.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:There are places where it is correct coding to use i++ or i-- as parts of expressions, for example when assigning to array elements...

Hmmm. Not so sure I agree...at least with the word "correct".

It'll certainly work, but unless you can show (maybe by running javap and looking at the resulting pcode) that there's any advantage to be gained from embedding increments (as there often is in C/C++), I think I'd go with Piet's advice - Keep 'em separate.

That said, I sometimes break that "rule" myself.

Winston
 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually I was going through the section 15.7 of JLS - and the JLS says this very fine thing, which I think is really worth quoting.

"15.7. Evaluation Order

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

It is recommended that code not rely crucially on this specification. Code is usually clearer when each expression contains at most one side effect, as its outermost operation, and when code does not depend on exactly which exception arises as a consequence of the left-to-right evaluation of expressions."

I think that is really a very clear guideline.

Edit : And if we go through the examples, and read further, we can see some more such guidelines.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Robert Stepp wrote:
Henry Wong wrote:
... "Precedence" or "Order of Evaluation" are *not* the same thing. Higher precedence doesn't mean done first.

Henry

I thought the whole point of "precedence" was to determine the proper order of operations? If this is not the case, what is really going on here? What is the point of establishing an order of precedence among operators?


First of all, the main issue with this topic has nothing to do with precedence. You are confused with how the prefix and postfix increment operators works. This has nothing to do with precedence.

This is then compounded with confusion of what precedence is, as you believe that precedence and order of evaluation are the same. So, now you have two issues.

Why am I pointing this out? Basically, this topic is about two issues, meaning there are two topics of discussions going on simultaneously..


So regarding the precedence question (which is not related to pre/post fix discussion).... Let's use math as an example, as you should already know precedence from basic math.

Take this example...



as you know multiplication has higher precedence than addition, so that expression is like this one...



So, how to do this? Well... you probably now do the multiplication first, and then add two to the result. Right? This is why you think that precedence and order of evaluation are related.

In Java, order of evaluation is defined by the JLS, as mostly going from left to right (you have to read the JLS for exceptions). Java goes left to right, processing as it goes along, and in order to maintain precedence, it will use temporary memory as needed.

Henry




 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote: . . .
Hmmm. Not so sure I agree...at least with the word "correct".
. . .
It is correct in the sense of the word defined by Tony Hoare, that it will maintain the class' invariants.
You can always replace
myArray[i++]...;
with
myArray[i]...; i++;
and you can replace
myArray[++i]...;
with
i++; myArray[i]...;
 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Yes, the operators were copied from C/C++, but their behaviour is not strictly defined in those languages. It is strictly defined in Java®.


Thanks, Campbell. Knowing this was important for me. I wasn't sure about it... since several days.

Henry, you have mentioned in several posts of yours ( in this one and in a couple of posts I have read earlier ) that precedence is not the same as evaluation order. I always thought that this was more like
reordering of instructions that could happen for as long as the end result of an expression ( which I thought depended on associativity and precedence alone) was the same.

After reading the following
Henry Wong wrote:In Java, order of evaluation is defined by the JLS, as mostly going from left to right (you have to read the JLS for exceptions).


and the relevant JLS chapter 15.7, I could understand the difference between order of evaluation and the order of execution of sub-expressions. I now understand ( I hope that I have understood it correctly this time)
that the rule quoted above affects the evaluation order and that can also affect the result of an expression. Operator precedence does not affect the order in which the sub-expressions are evaluated, it just affects the execution order of operators relative to each other.

So, thank you. I think I understand it better now ( I hope).

I also found this excellent post in StackOverflow.com and Eric Lippert's response in this post was particularly helpful.
So Eric, if you happen to read this someday, thanks a lot.








 
Tedy Kwan
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is easy to understand y=x++; but it is difficult to see y =y++; is the same as y=y;
I under stand Java evaluate left to right, so after the assignment; the +1 operation ... vanish?
Could some one explain that?
 
Tedy Kwan
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tedy Kwan wrote:It is easy to understand y=x++; but it is difficult to see y =y++; is the same as y=y;
I under stand Java evaluate left to right, so after the assignment; the +1 operation ... vanish?
Could some one explain that?

Found the explanation here http://stackoverflow.com/questions/7911776/what-is-x-after-x-x
---------8<--------
tmp = y;
y = y + 1;
y = tmp;
---------8<--------
 
Junilu Lacar
Sheriff
Posts: 11476
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It was answered and explained in another thread here on the Ranch just today, too.

https://coderanch.com/t/679329/java/Postfix-unary-operator
 
Mark Spencers
Ranch Hand
Posts: 51
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The only difference is that the prefix version (++x) evaluates to the incremented value, whereas the postfix version (x++) evaluates to the original value. If you are just performing a simple increment/decrement, it doesn't really matter which version you choose. But if you use this operator in part of a larger expression, the one that you choose may make a significant difference.
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16057
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And since this is a frequently asked question, we have a Wiki page which explains it: https://coderanch.com/wiki/659942/Post-Increment-Operator-Assignment
 
div tripathi
Ranch Hand
Posts: 31
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Increment operator :  ++ i ;    i ++ ;
Decrement operator :  – – i ;   i – – ;

#include <stdio.h>
int main()
{
     int i=1;
     while(i<10)
     {
         printf("%d ",i);
         i++;
     }   
}

You can check above code and run it accordingly
 
Junilu Lacar
Sheriff
Posts: 11476
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
div tripathi wrote:You can check above code and run it accordingly

A few things about your example:
1. It's not Java (but close enough, so no biggie)
2. It's not good code, even for C/C++
3. It has nothing to do with the issue regarding the postfix operator that is discussed in the thread
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mark Spencers wrote:The only difference is that the prefix version (++x) evaluates to the incremented value, whereas the postfix version (x++) evaluates to the original value. . . .
I think that is only part of the story. Another part of the story is that such code can be relied upon to confuse inexperienced programmers. And yet another part of the story is that there are (for a very short time) two values, that of x and that of the whole expression. Only in the case of x++ the two values are different, as MS said, and for ++x they are the same.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!