post increment confusion (OCPJP forum at Coderanch) (original) (raw)

posted 21 years ago

Hi,this code confused me on how post-increment works:
public class Shift{
static int i;
public static void main(String argv[]){
i = 2; //line 1
i =i++; //line 2
System.out.println(i); //line 3
}
}
Before i run this code, i thought the output would be 3 but surprisingly, it printed out 2. In line 2, i is assigned the original value of i which is 2, then it gets incremented to 3 before it gets printed. How come the value being printed in the console is still 2? Does this mean i in line 2 didn't increment at all?
Really confused... can somebody enlighten me. thanks.

posted 21 years ago

hi
it is because the value of i is evaluated before incrementing, if u do
i= ++i
u will have 3

There was a young man of Cadiz
Who inferred that life is what it is ,
for he early learnt ,
If it were what it weren't ,
it could not be that which it is

nikki lorenzo

Greenhorn

Posts: 28

posted 21 years ago

thanks luc. i agree that the value of i gets evaluated (i=2) before incremented. BUT the value of i is still incremented before printed right? then why is the output not reflecting the incremented value which is 3?

posted 21 years ago

Hi nikki,
this is what is happening:
i=2; //you are assigning the variable i to the value of 2
i=i++; //you are assigning i to i, which is 2 so i = 2,
//increment here, but the incremented value did not get assigned to anything so i=2,
example:
I hope this helps you to understand the post fix operator
Davy
[ March 13, 2004: Message edited by: Davy Kelly ]
[ March 13, 2004: Message edited by: Davy Kelly ]

How simple does it have to be???

nikki lorenzo

Greenhorn

Posts: 28

posted 21 years ago

thanks davy. looks like i'm seeing a pattern here. i revised my code into this:

when i used option A, the output is 3 4 5. it seems to me that the incremented value is assigned to i before printed. when i used option B output is 2 2 2. values of i are incremented but was never assigned to i.
does this mean that when we use a post-increment together with the assignment operator =, the incremented value is never assigned to the variable? did i get the concept right???

posted 21 years ago

Originally posted by nikki lorenzo:
does this mean that when we use a post-increment together with the assignment operator =, the incremented value is never assigned to the variable? did i get the concept right???

In this case, that's exactly what's happening.

Davy Kelly

Ranch Hand

Posts: 384

posted 21 years ago

when i used option A, the output is 3 4 5. it seems to me that the incremented value is assigned to i before printed. when i used option B output is 2 2 2. values of i are incremented but was never assigned to i.
does this mean that when we use a post-increment together with the assignment operator =, the incremented value is never assigned to the variable? did i get the concept right???


Hey Nikki,
Yes you got it
in your first option you did increment the value of i.
in your second, you assigned i to the value of i, then incremented.
here is a small program to show you what is happening;

you can probably get variable i no problem but j can be difficult to get,
so my breakdown is getting done again:
j = j++ //j=j so j=0 now increment

How simple does it have to be???

nikki lorenzo

Greenhorn

Posts: 28

posted 21 years ago

now i'm getting it... thanks for all the help guys!
[ March 13, 2004: Message edited by: nikki lorenzo ]

posted 21 years ago

I haven't been following this conversation, so this might by a non sequitur. But I happen to have this example handy.
Here is how post-increment works.
i++
load (read) the value of the variable i
The value of the expression i++ is that value.
Then add one to the variable i.

[ March 13, 2004: Message edited by: Marlene Miller ]

posted 21 years ago

I am still a bit confuse.
In the last piece of code,

Does that means that the increment, does not take place at the "operand stack"? If not, where does the post-increment, for the variable i++ take place?
Edited by Corey McGlone: Broke up long code string to preserve formatting
[ March 15, 2004: Message edited by: Corey McGlone ]

Frankie Chee

Ranch Hand

Posts: 43

posted 21 years ago

Oops so sorry for that, I thought the indents would be
copied as long as I put them within the code tag.
[ March 15, 2004: Message edited by: Frankie Chee ]

Davy Kelly

Ranch Hand

Posts: 384

posted 21 years ago

frankie,
there is a button in all of the posts that look like a piece of paper with a pencil,
click this and amend your post, don't use tabs,
use the return/enter button to break up the lines,
use the space bar to indent 2 spaces is the norm in here,
this makes your post a lot easier to read and get people to
answer you quicker.
you can only edit your own posts, the bigwigs can edit anyones
Davy
see how below has an Edited part in square brackets.
[ March 15, 2004: Message edited by: Davy Kelly ]

How simple does it have to be???

Davy Kelly

Ranch Hand

Posts: 384

posted 21 years ago

Frankie,
use my explanation just below Coreys post.
now use this way of doing the post/pre increments, with a value of j= 27;
I think Marlenes post is very confusing, about the increment then take away, how do you know you want to take what away, when should that happen.
Not everyone can understand such things, I prefer to look at things like a kid, and I like things to be explained to me like a kid, it makes things much easier.
the best thing to remember is that if you end a statement on a j++ that post increment did not work, if you get ++j this did, if you have a j then just add what the value of j was at that time.
here is 3 examples:
j=0;
j= ++j + ++j + j; //what is j?
j=0;
j= j++ + j + j++; //what is j?
j=0;
j= j + j++ + ++j; //what is j?
Davy

How simple does it have to be???

Frankie Chee

Ranch Hand

Posts: 43

posted 21 years ago

applying what you have said, that should be:
1+2+2=5;
0+1+1=2;
0+0+2=2;
this should be very useful during the exam, save quite a bit of trouble too.
Now I know how to amend the post, look more tidy now

[ March 15, 2004: Message edited by: Frankie Chee ]

Marlene Miller

Ranch Hand

Posts: 1392

posted 21 years ago

Hi Frankie.
>> Does that means that the increment, does not take place at the "operand stack"?
Correct. The increment occurs in the local variable.
>> If not, where does the post-increment, for the variable i++ take place?
One possible model of a thread stack

1. i = 2;
A. Load (push) constant 2 onto operand stack.
B. Pop from operand stack and store into local variable i.

2a. i++
C. Load (push) value of variable i onto operand stack.

2b. Increment the local variable i.

The value of the expression i++ is 2.
The value of the variable i is 3.
3. i =
E. Pop from operand stack and store into the variable i.

[ March 15, 2004: Message edited by: Marlene Miller ]

Marlene Miller

Ranch Hand

Posts: 1392

posted 21 years ago

>> I think Marlene's post is very confusing
Do I get a second chance?

i++
B: Load (read) the value of the variable i and push onto the operand stack.
The value of the expression i++ is that value on the operand stack.
C: Then add one to the variable i.
[ March 15, 2004: Message edited by: Marlene Miller ]

Davy Kelly

Ranch Hand

Posts: 384

posted 21 years ago

Hey Marlene,
I did not mean anything bad by saying your explanation was confusing, but I had a look at your last two posts, and I must admit, I still don't understand it your way, must just be the way I have been taught, but in saying that, I think it is a long way for the same thing.
But you have taken your time on it, what are the diagrams about, which side does what??? I am confused. Please could you explain to me
Frankie,
(quote)
1+2+2=5;
0+1+1=2;
0+0+2=2;
Yes you have got it absolutley corect, now try it yourself, make up 3 or four different versions, with different endings, make them large to see if you can still get it, then compile them and see if you get them correct.
but try to do it from another number instead of 0, like
j=5;
j = ++j + ++j + j + j++ + ++j;
6 + 7 + 7 + 7 + 9 = 36
Good luck Frankie
Davy

How simple does it have to be???

Marlene Miller

Ranch Hand

Posts: 1392

posted 21 years ago

>> saying your explanation was confusing
What you say helps me to be better next time.
>> what are the diagrams about
Hi Davy,
When the Java virtual machine invokes a method, it allocates some memory space for the local variables.

The Java virtual machine also allocates some memory space for computing expressions � a work space.

This region of memory for computing expressions is treated as a stack. Values are pushed onto the stack and popped from the stack. Values are moved between this operand stack and the local variables.
When the Java virtual machine computes the expression i++, things happen on the operand stack and things happen in the memory cell for variable i.
The value in the local variable is copied to a memory cell on the operand stack. That is the value of the expression i++. Then the value in the memory cell for variable i is incremented.
The value of the expression is on the operand stack.
The increment occurs in the memory cell for variable i.
j = i++
When the result of the expression i++ is assigned to another variable, the value on the operand stack is popped from the stack and moved to the memory cell for the variable j.
Some people are visual. If they can see what is happening in memory, they can understand better.
[ March 15, 2004: Message edited by: Marlene Miller ]

posted 21 years ago

Originally posted by Marlene Miller:
Some people are visual. If they can see what is happening in memory, they can understand better.

Like myself.
No kidding, I couldn't understand the whole i=i++ thing before your last 2 or 3 posts. Now it's all crystal clear.

Marlene Miller

Ranch Hand

Posts: 1392

posted 21 years ago

Thank you Bojan. I am learning. Draw pictures. But then explain the pictures.

Davy Kelly

Ranch Hand

Posts: 384

posted 21 years ago

Hey Marlene,
So in your diagram, if i can do this correctly, is

Have I understood your diagram and explanaition?
Davy
[ March 16, 2004: Message edited by: Davy Kelly ]

How simple does it have to be???

Marlene Miller

Ranch Hand

Posts: 1392

posted 21 years ago

Hi Davy. You are close. The value of the expression i++ (which is 1) ends up on the operand stack. Thank you for trying out this new way of analyzing code.
Here is what we are working on.

Let's take it one step at a time.
(1) i = 1;
iconst_1 : Push the constant 1 onto the operand stack.

istore_1 : Pop from the operand stack and store in the local variable i

(2) i++
iload_1 : Load (read) the variable i and push onto the operand stack

iinc 1, 1 : Increment the local variable by 1

(3) j =
istore_2 : Pop from the operand stack and store in the local variable j

[ March 16, 2004: Message edited by: Marlene Miller ]

posted 21 years ago

1. Marlene, first I was having a mental block with the previous thread on pre post increment. My C days still haunt me. I have clarification now.
2. I think it is great drawing pictures to explain things. I do see the confusion that some others are having with the stack. That is a hard thing to draw a picture of. Think about drawing the runtime stack with recursion!!!
I have found drawing pictures helps with:
1. pointers (C , C++)
2. and data structures (i.e. linked lists, stacks, queues etc.)

I personally do not draw pictures with ++/-- explaination or with recursion. I use a simple trick with recursion and tell my students to "rewrite the code" with ++/--.
Just my thoughts.
[ March 16, 2004: Message edited by: James Chegwidden ]
[ March 16, 2004: Message edited by: James Chegwidden ]

Author and Instructor, my book

Marlene Miller

Ranch Hand

Posts: 1392

posted 21 years ago

Hi James. Thank you for your ideas.
It's much better to see the thread stack in debug, changing in real time. As raw data, no fancy windows graphics.
My guess is the trouble with i++ for many people is: where does i++ occur if not in the variable i. They have not been told expressions are computed somewhere else (an arithmetic unit, registers, operand stack) and the result stays there until assigned. Incrementing the variable is a side effect.
[ March 16, 2004: Message edited by: Marlene Miller ]

Davy Kelly

Ranch Hand

Posts: 384

posted 21 years ago

so what you are saying is that after the operand stack has popped it to the local variable, the operand stack gets a copy, because the both of them are one, you add these together, to make the local variable 2 but the opeand is still only one, then you pop it to j's local varibale???
I just can't see it your way
Davy

How simple does it have to be???

Marlene Miller

Ranch Hand

Posts: 1392

posted 21 years ago

Hi Davy.
Access to data in memory is faster than access to data on disks. Access to data in hardware registers is even faster. Hardware registers are expensive. So there are only about 8 of them (or as many as 32).

When the operating system has to do arithmetic, temporary results are stored in the registers. First the operating system reads data from memory into the registers.

Then the operating system does the arithmetic. 5 + 24 = 29

Then the operating saves the result in memory.

z = x + y;
The operand stack in the Java virtual machine is like registers. It is a place for doing temporary things. It is a place for computing the value of an expression.
i = 3;
i++; // Oh no, not this again
The value of the expression i++ is 3. That value is computed in the registers. There isn�t much computation to do. The value is moved from memory (variable i) to the registers.

i++ is an unusual expression, because it has a side effect. The side effect is that 1 is added to a variable i in memory (sort of behind the scenes).

Since this is the postfix increment (not the prefix increment) the side effect occurs after (not before) computing the value of the expression in the registers.
Marlene
[ March 16, 2004: Message edited by: Marlene Miller ]

Davy Kelly

Ranch Hand

Posts: 384

posted 21 years ago

hey marlene,
so:

Ok i got your arithmetic diagram, I like your explanaition, but have i understood you for this one bold has been added by me, hope it works.
Davy

How simple does it have to be???

Marlene Miller

Ranch Hand

Posts: 1392

posted 21 years ago

Hi Davy, that is exactly correct. You've got it right.
(I decided to erase something that I wrote here. You worked hard to follow me. It's time to relax. Corey is responding below to what I wrote. I hope you don't mind Corey.)
[ March 17, 2004: Message edited by: Marlene Miller ]

Corey McGlone

Ranch Hand

Posts: 3271

posted 21 years ago

Originally posted by Marlene Miller:
You'll figure out what the byte codes are doing. And you will settle the argument.
It's not something you use everyday. But it's good for finding out what the compiler does, when everyone else is guessing.

One thing to keep in mind, Marlene, is that not all compilers are equal. There are a number of Java compilers out there and some may make various optimizations or have some idiosyncrasies not seen in other compilers.
My suggestion is to always look to the JLS if you're confused. You can go to the compiler for a lot of things, but the JLS is the "end all" source for Java - that's what everything, including the compilers, are based from.

Davy Kelly

Ranch Hand

Posts: 384

posted 21 years ago

hey marlene, ok i see where you are going now, i think my main problem was not knowing what the cells ehre, either operand / variable
Davy

How simple does it have to be???

posted 21 years ago

Maha Anna explained good shortcuts for post increment operator questions. It is very interesting. Please check out here

Thanks,
Durgaprasad
SCJP1.4, SCWCD1.4, SCBCD1.3,
SCEA

posted 21 years ago

A lot has been posted on this thread already, but I think the topic still warrants clarification.
Firstly, consider the statement
j = i++;
Folks often want to read that as something like "j is assigned the value of i and then i is incremented." But that is not correct. It has to be read like "the expression on the right is evaluated and the result is assigned to j." This makes all the difference, as we will see.
Looking at the original statement now:
i = i++;
where i is equal to 2 going in. The expression on the right is a single term, so the value of the expression is the value of that term. By definition, the value of the term is 2 -- it's a post increment on a variable initially equal to 2. When the term is evaluated, any side effects also occur at that time; so i is incremented to 3, but the value of the term (and the expression) is still 2. Now the value of the expression is assigned to i; hence the final value of i is 2, not 3.
Hope that helps.
---
Jerry
[ March 18, 2004: Message edited by: JL Henderson ]

James Chegwidden

Author

Posts: 201

posted 21 years ago

It usually is a matter of semantics. There are usually many different ways of saying the same thing.

Author and Instructor, my book

nikki lorenzo

Greenhorn

Posts: 28

posted 21 years ago

huh, lost track of this post since my last reply. just some big proof that i was not the only one confused with this pretty tricky topic.
anyway, i agree with Durgaprasad. maha anna's approach removes all the complications to this topic. i wouldn't have started this thread had i seen maha anna's explanation earlier. so all you guys out there still confused, i suggest you click this link first: pre/post increment made simple
[ March 18, 2004: Message edited by: nikki lorenzo ]

posted 21 years ago

Davy,
Don't concentrate on the finger or you will miss all that heavenly glory

La Vish
SCJP 1.4, President 60s Club

posted 21 years ago

Great explanations up there...

Davy Kelly

Ranch Hand

Posts: 384

posted 21 years ago

thanks la vish for noticing my signature
davy

How simple does it have to be???

Marlene Miller

Ranch Hand

Posts: 1392

posted 21 years ago

Since we are exploring the increment operator in great detail in this thread, I'd like to present something I read by Andrew Koenig in Accelerated C++. Koenig is introducing ++i to the new C++ student.
He remarks that he could have used i = i + 1, but incrementing an object [notice he says an object, not a number] is so common that a special notation for doing so is useful.
Moreover, the idea of transforming a value into its immediate successor, in contrast with computing an arbitary value, is so fundamental to abstract data structures that it deserves a special notation for that reason alone.
++i : transforming a value into its immediate successor
In a later chapter, he follows up on this remark with a more general representation, namely, the iterator.

posted 21 years ago

I think this might be a good place for K&B to further clarify their "Two Minute drill" notes:
They say:
"Prefix operator runs before the value is used in the expression."
"Postfix operator runs after the value is used in the expression."
"In ANY expression, both operands are fully evaluated before the operator is applied."
They obviously mean the non-post/prefix operator.
So...
i = 2; //line 1
i =i++; //line 2
System.out.println(i); //line 3 prints 2
System.out.println(i++); //line 4 still prints 2
Q is:
Define "expression". Seems that an expression requires a equality or comparsion operator. And "=" doesn't count as either because it's an assignment operator.
[ March 24, 2004: Message edited by: R Hayes ]

Marlene Miller

Ranch Hand

Posts: 1392

posted 21 years ago

(Not specific to Java) an expression consists of a literal or a named variable, or an operator or function applied to a collection of operands or arguments, each of which in turn is an expression.
In Java, the simplest kinds of expression are
(1) primary expressions, including literals, class literals, field access, method invocation, array access, object creation: 10 "string" m() a[i] new C() m().x
(2) expression names, which are simple names or qualified names of variables: x p.x C.x
Expressions can be formed by combining primary expressions, expression names and expressions with the unary, binary, and ternary operators.

And "=" doesn't count as either because it's an assignment operator.

a = 3 is an assignment expression. The value of the expression is 3. As a side effect, 3 is stored in the variable a.

x = new C() is an assignment expression. The value of the expression is a reference to an object of type C. (x = new C()).y is a field access expression. The value of the expression is the variable y. (x = new C()).y = 10 is an assignment expression. The value of the expression is 10.
[ March 22, 2004: Message edited by: Marlene Miller ]