views:

6062

answers:

26

Hi, I'm a teacher, and yesterday a student wrote the following code:

public class Tests {

    public static void main(String[] args) throws Exception {
        int x = 0;
        while(x<3) {
            x = x++;
            System.out.println(x);
        }
    }
}

we know he should have writen just x++ or x=x+1, but on x = x++; it should first attribute x to itself, and later increment x. Why does x continue with 0 as value?

--update

Here's the bytecode:

public class Tests extends java.lang.Object{
public Tests();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[])   throws java.lang.Exception;
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   iconst_3
   4:   if_icmpge   22
   7:   iload_1
   8:   iinc    1, 1
   11:  istore_1
   12:  getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   15:  iload_1
   16:  invokevirtual   #3; //Method java/io/PrintStream.println:(I)V
   19:  goto    2
   22:  return

}

I'll read about the instructions to try to understand...

+11  A: 

This statement:

x = x++;

evaluates like this:

  1. Push x onto the stack;
  2. Increment x;
  3. Pop x from the stack.

So the value is unchanged. Compare that to:

x = ++x;

which evaluates as:

  1. Increment x;
  2. Push x onto the stack;
  3. Pop x from the stack.

What you want is:

while (x < 3) {
  x++;
  System.out.println(x);
}
cletus
Definitely the correct implementation, but the question is 'why?'.
p.campbell
The original code was using post-increment on x and then assigning it to x. x will be bound to x before increment, therefore it will never change values.
birryree
Why did this get downvoted?
cletus
Why has this answer been down voted? Good answer @cletus... beat me to it :-)
ILMV
@cletus I am not the downvoter, but your initial answer didn't contain the explanation. It just said do 'x++`.
Petar Minchev
@cletus: I didn't downvote, but your answer originally was just the `x++` code snippet.
p.campbell
It's called a "work in progress" and would've had to have been like 30 seconds in. Downvote for a partial answer 30 seconds old? Really?
cletus
@cletus There was also an upvote for the partial answer. Really strange...
Petar Minchev
The explanation is incorrect too. If the code first assigned x to x and then incremented x, it would work fine. Just change `x++;` in your solution to `x=x; x++;` and you're doing what you claim the original code is doing.
Wooble
The OP wasn't asking for a correct implementation, but for clarification on the expected behavior. He said that the code was a submission from his student, and that he knew that the syntax wasn't semantically sound.
sidewaysmilk
This answer should probably be deleted; the solution doesn't answer the question and its explanation is patently wrong. Newbies that come here will only see that it has a fairly large positive score, not being able to know the huge amounts of downvotes.
Mark Peters
+2  A: 

this is because it never gets incremented in this case, x++ will use the value of it first before incrementing like on this case it will be like

x = 0;

but if you do ++x; this will increase.

mezzie
if you make a test, you can see that it first increments, and later attributes. So it should not attribute zero.
Tom Brito
@Tom: see my answer - I show in a test that x++ actually returns the old value of x. That's where it breaks.
Robert Munteanu
+97  A: 

x = x++ works in the following way:

  • First it evaluates expression x++. Evaluation of this expression produces an expression value (which is the value of x before increment) and increments x.
  • Later it assigns the expression value to x, overwriting incremented value.

So, the sequence of events looks like follows (it's an actual decompiled bytecode, as produced by javap -c, with my comments):

   8:   iload_1         // Remember current value of x in the stack
   9:   iinc    1, 1    // Increment x (doesn't change the stack)
   12:  istore_1        // Write remebered value from the stack to x

For comparison, x = ++x:

   8:   iinc    1, 1    // Increment x
   11:  iload_1         // Push value of x onto stack
   12:  istore_1        // Pop value from the stack to x
axtavt
if you make a test, you can see that it first increments, and later attributes. So it should not attribute zero.
Tom Brito
@Tom that's the point, though - because this is all a single sequence it's doing things in a non-obvious (and probably undefined) order. By attempting to test this you're adding a sequence point and getting different behaviour.
Rup
Regarding your bytecode output: note that `iinc` increments a variable, it doesn't increment a stack value, nor does it leave a value on the stack (unlike almost every other arithmetic op). You might want to add the code generated by `++x` for comparison.
Anon
@Rep It may not be defined in C or C++, but in Java, it is well defined.
ILMTitan
It is well defined in C ... but not terribly obvious.
Jaydee
+1 for bytecode.
Platinum Azure
+1 for knowing the problem, but could have explained better: Where people seem to be confused- they think that "x" is a single entity. It's stored into itself, then incremented. The fact is, "x" is actually two variables in memory. There is "x" in RAM and "x" in the register. You're copying the value of "x" in RAM to "x" in the register, incrementing "x" in RAM, then copying the value of "x" in the register to "x" in RAM.
steven_desu
steven: Your explanation gets a little closer, but even that is not entirely accurate, since optimization could cause the value of x to stay in a register the entire time. It doesn't necessarily have to go to RAM at all unless your method runs out of free registers.
StriplingWarrior
Something to say about my last comment on the question?: It's very strange that in C language the behavior is different. Maybe in C it first read the value and then, later, it increments, while in Java it increments then return the old value..
Tom Brito
@Jaydee @Tom Brito - AFAIK it's undefined because there is no sequence point between assignment and increment.
detly
@Detly you are correct I've had a chance to look at the language spec. I find it odd though.
Jaydee
@Jaydee - it's only odd if you think the point of the standard is to specify the behaviour of *every possible combination of syntactically valid constructs*, but it's not. It's undefined because it was better to give compiler writers leeway on certain other things than to specify perverse constructs like this.
detly
@Detly- I'd say the purpose of a standard is that a piece of code will operate the same way when compiled irrespective of the particular compiler used. I'd argue that the order of evaluation as occurs in the original question is the only correct one acording to the definitions given. Go figure, perhaps somebody (maybe me) should put a query into ISO/ANSI
Jaydee
@Jaydee - almost... the purpose of the standard is that *standard conforming code* will operate the same way :) At any rate, there was (and maybe still is) an advantage to not specifying sequence points under every possible circumstance in C, but it's not really an advantage in Java.
detly
Interesting article http://www.angelikalanger.com/Articles/VSJ/SequencePoints/SequencePoints.html
Jaydee
@Jaydee - thanks, that's getting bookmarked :)
detly
+55  A: 

This happens because the value of x doesn't get incremented at all.

x = x++;

is equivalent to,

int temp = x;
x++;
x = temp;

Explanation:

Lets look at the byte code for this operation. Consider a sample class:

class test {
        public static void main(String[] args) {
                int i=0;
                i=i++;
        }
}

Now running the class disassembler on this we get:

$ javap -c test
Compiled from "test.java"
class test extends java.lang.Object{
test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   iinc    1, 1
   6:   istore_1
   7:   return    
}

Now the Java VM is Stack Based which means for each operation, the data will be pushed onto the stack and from stack the data will popped out to perform the operation. There is also another data structure, typically an array to store the local variables.The local variables are given ids which are just the index to the array.

Let us look at the mnemonics in main() method:

  • iconst_0: The constant value 0 is pushed on to the stack.
  • istore_1: The top element of the stack is popped out and stored in the local variable with index 1
    which is x.
  • iload_1 : The value at the location 1 that is value of x which is 0, is pushed into the stack.
  • iinc 1, 1 : The value at the memory location 1 is incremented by 1. So x now becomes 1.
  • istore_1 : The value at the top of the stack is stored to the memory location 1. That is 0 is assigned to x overwriting its incremented value.

Hence the value of x does not change resulting in the infinite loop.

codaddict
Actually it gets incremented (thats the meaning of `++`), but the variable gets overwritten later.
Progman
`int temp = x; x = x + 1; x = temp;` its better not to use a tautology in your example.
Scott Chamberlain
+2  A: 

The value stays at 0 because the value of x++ is 0. In this case it doesn't matter if the value of x is increased or not, the assignment x=0 is executed. This will overwrite the temporary incremented value of x (which was 1 for a "very short time").

Progman
But x++ is a post operation. So x would have to be incremented after the assignment is complete.
Sagar V
@Sagar V: only for the expression `x++`, not for the whole assignment `x=x++;`
Progman
No, I think it only needs to be incremented after the value of x to be used in the assignment was read.
Rup
+1  A: 

Think of x++ as a function call that "returns" what X was before the increment (that's why it's called a post-increment).

So the operation order is:
1: cache the value of x before incrementing
2: increment x
3: return the cached value (x before it was incremented)
4: return value is assigned to x

jhabbott
OK, but what specifies the order of steps 3 and 4?
Rup
"returns what X was before the increment" is wrong, see my update
Tom Brito
In reality steps 3 and 4 are not separate operations - it's not *really* a function call that returns a value, it just helps to think of it that way. Whenever you have an assignment the right hand side is "evaluated" then the result is assigned to the left hand side, the evaluation result can be thought of as a return value as it helps you to understand the order of operations, but it's not really.
jhabbott
Oops, true. I meant steps 2 and 4 - why does the returned value get stored over the top of the incremented value?
Rup
This is part of the definition of an assignment operation, first the right hand side is completely evaluated, then the result is assigned to the left hand side.
jhabbott
@jhabbot. Nearly right, technically x++ happens after expression evaluation (think of (x=a++ + b++)), but before the assignment as ++ has higher operator precedence.
Jaydee
+5  A: 

You're effectively getting the following behavior

  1. grab the value of x (which is 0) as "the result" of the right side
  2. increment the value of x (so x is now 1)
  3. assign the result of the right side (which was saved as 0) to x (x is now 0)

The idea being that the post-increment operator (x++) increments that variable in question AFTER returning it's value for use in the equation it's used in.

Edit: Adding a slight bit because of the comment. Consider it like the following:

x = 1;        // x == 1
x = x++ * 5;
              // first, the right hand side of the equation is evaluated
  ==>  x = 1 * 5;    
              // x == 2 at this point, as it "gave" the equation it's value of 1
              // and then gets incremented by 1 to 2
  ==>  x = 5;
              // and then that RightHandSide value is assigned to 
              // the LeftHandSide variable, leaving x with the value of 5
RHSeeger
OK, but what specifies the order of steps 2 and 3?
Rup
@Rup - The language defines it. The right side of the equation is evaluated first (in this case, "x++"), and the result is assigned to the variable on the left side. That's how the language works. As far as the "x++" "returning" x for the equation, that's how the postfix increment operator works (return the value of x, then increment it). If it had been "--x", then it would have been (increment x, then return the value). Return isn't the right word there, but you get the idea.
RHSeeger
+5  A: 

From http://download.oracle.com/javase/tutorial/java/nutsandbolts/op1.html

The increment/decrement operators can be applied before (prefix) or after (postfix) the operand. The code result++; and ++result; will both end in result being incremented by one. The only difference is that the prefix version (++result) evaluates to the incremented value, whereas the postfix version (result++) 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.

To illustrate, try the following:

    int x = 0;
    int y = 0;
    y = x++;
    System.out.println(x);
    System.out.println(y);

Which will print 1 and 0.

Colin Cochrane
It's not the evaluation result that's the issue, though, it's the order of the stores.
Rup
I disagree. If x = 0 then x++ will return 0. Therefore x = x++ will result in x = 0.
Colin Cochrane
Rup is right about this. It's the order of the stores which is at issue in this particular case. y=x++ isn't the same as x=x++; On the latter one, x is being assigned 2 values in the same expression. Left hand x is being assigned the result of the *evaluation* of the expression x++, which is 0. Right hand side x is being incremented to 1. In which order these 2 assignment occur is what the issue is about. From previous posts it is clear that the way this works is: eval = x++ => eval == 0 : increment right x => x == 1 : left x = eval => x == 0
mike
+27  A: 
  1. Prefix notation will increment the variable BEFORE the expression is evaluated.
  2. Postfix notation will increment AFTER the expression evaluation.

However "=" has a lower operator precedence than "++".

So x=x++; should evaluate as follows

  1. x prepared for assignment (evaluated)
  2. x incremented
  3. Previous value of x assigned to x.
Jaydee
+1 for first actual explanation of why ++ then =
Rup
This is the best answer. Some markup would have helped it stand out a bit more.
sidewaysmilk
This is wrong. It's not about precedence. `++` has higher precedence than `=` in C and C++, but the statement is undefined in those languages.
Matthew Flaschen
+18  A: 

None of the answers where quite spot on, so here goes:

When you're writing int x = x++, you're not assigning x to be itself at the new value, you're assigning x to be the return value of the x++ expression. Which happens to be the original value of x, as hinted in Colin Cochrane's answer .

For fun, test the following code:

public class Autoincrement {
        public static void main(String[] args) {
                int x = 0;
                System.out.println(x++);
                System.out.println(x);
        }
}

The result will be

0
1

The return value of the expression is the initial value of x, which is zero. But later on, when reading the value of x, we receive the updated value , that is one.

Robert Munteanu
I'll try to understand the bytecode lines, see my update, so it'll be clear.. :)
Tom Brito
Using println() was very helpful to me in understanding this.
Emtucifor
+1  A: 

This works how you expect the other one to. It's the difference between prefix and postfix.

int x = 0; 
while (x < 3)    x = (++x);
iterationx
+156  A: 

Perhaps if we write out a method to do the equivalent of what x++ does it will make this clearer.

(Note: this is C# code for the purpose of illustration. Unless I'm mistaken there's actually no way to pass a parameter by reference in Java.)

public static int PostIncrement(ref int x)
{
    int valueBeforeIncrement = x;
    x = valueBeforeIncrement + 1;
    return valueBeforeIncrement;
}

Right? Increment the value passed and return the original value: that's the definition of the postincrement operator.

Now, let's see how this behavior plays out in your example code:

int x = 0;
x = PostIncrement(ref x);

PostIncrement(ref x) does what? Increments x, yes. And then returns what x was before the increment. This return value then gets assigned to x.

So the order of values assigned to x is 0, then 1, then 0.

This might be clearer still if we re-write the above:

int x = 0;                       // x is 0.
int temp = PostIncrement(ref x); // Now x is 1, and temp is 0.
x = temp;                        // Now x is 0 again.

Your fixation on the fact that when you replace x on the left side of the above assignment with y, "you can see that it first increments x, and later attributes it to y" strikes me as confused. It is not x that is being assigned to y; it is the value formerly assigned to x. Really, injecting y makes things no different from the scenario above; we've simply got:

int x = 0;                       // x is 0.
int y = 0;                       // y is 0.
int temp = PostIncrement(ref x); // Now x is 1, and temp is 0.
y = temp;                        // y is still 0.

So it's clear: x = x++ effectively does not change the value of x. It always causes x to have the values x0, then x0 + 1, and then x0 again.


Update: Incidentally, lest you doubt that x ever gets assigned to 1 "between" the increment operation and the assignment in the example above, I've thrown together a quick demo to illustrate that this intermediate value does indeed "exist," though it will never be "seen" on the executing thread.

The demo calls x = x++; in a loop while a separate thread continuously prints the value of x to the console.

The code is in Java, but I warn you: I have basically zero experience in Java (I only even answered this question because I felt I could explain what was happening with the ++ operator). So this code might be hideous to a seasoned Java developer.

public class Main {
    public static volatile int x = 0;

    public static void main(String[] args) {
        LoopingThread t = new LoopingThread();
        System.out.println("Starting background thread...");
        t.start();

        while (true) {
            x = x++;
        }
    }
}

class LoopingThread extends Thread {
    public @Override void run() {
        while (true) {
            System.out.println(Main.x);
        }
    }
}

Below is an excerpt of the above program's output. Notice the occasional occurrence of 1 amongst a flurry of 0s.

Starting background thread...
0
0
1
1
0
0
0
0
0
0
0
0
0
0
1
0
1
Dan Tao
Great example, I'll use this to explain in the class. Thanks!
Tom Brito
By the way, to do this example in java you can create a class to hold the value, but would be more complicated.. Cool this C# feature..
Tom Brito
You don't need to create a class to pass by reference in java (though that would certainly work). You can use the `Integer` class, which is part of the standard library, and it even has the benefit of being auto-boxed to and from `int` _almost_ transparently.
rmeador
Bravo... Didn't see what was wrong until half way thru, but it makes perfect sense.
WernerCD
@rmeador Integer is immutable, so you still couldn't change its value. AtomicInteger, however, is mutable.
ILMTitan
@rmeador: I'm asking because I honestly don't know, not to challenge you: how would this work, what you're suggesting? What I mean is, how can you assign a new value to `x` from within a method, even if it *is* boxed as an `Integer`? (Is the `Integer` type not immutable?) I know that in .NET, using C# for example, you could box an `int` as `object` but you still wouldn't be able to *assign* a new value to the variable holding that `int` from within a method, unless it were passed as a `ref` parameter.
Dan Tao
@Dan Tao: yeah, as @ILMTitan points out, it's immutable... I forgot that little detail. The suggestion of AtomicInteger seems reasonable, but I don't think you get autoboxing with that class.
rmeador
@Dan: By the way, `x` in your last example must be declared `volatile`, otherwise it's an undefined behaviour and seeing `1`s is implementation specific.
axtavt
@axtavt: Good point -- I actually discovered this myself after last updating my answer when I changed the code only slightly and saw different behavior (all 0s, no 1s). I've updated the answer to include the `volatile` keyword so that the program's behavior is defined.
Dan Tao
+1 awesome use of a Race Condition to display the intermediate value.
Conrad Frix
simple answer: operator precedence of ++ before =. See http://www.cppreference.com/wiki/operator_precedence The "infinite loop" part of title is misleading.
burkestar
@burkestar: I don't think that link is *quite* appropriate in this case, since it's a Java question and (unless I'm mistaken) the behavior is actually undefined in C++.
Dan Tao
Something to say about my last comment on the question?: It's very strange that in C language the behavior is different. Maybe in C it first read the value and then, later, it increments, while in Java it increments then return the old value..
Tom Brito
@Tom Brito - in C it's not defined... the `++` *could* be done before or after assignment. Practically speaking, there might a compiler that does the same thing as Java, but you wouldn't want to bet on it.
detly
Brilliant answer! Now I get it.
Ed Daniel
+13  A: 

It has been already explained well by other. I just include the links to the relevant Java specification sections.

x = x++ is an expression. Java will follow the evaluation order. It will first evaluate the expression x++, which will increment x and set result value to the previous value of x. Then it will assign the expression result to the variable x. At the end, x is back at its previous value.

plodoc
+1. This is by far the best answer to the actual question, "Why?"
Matthew Flaschen
A: 

Please Please please tell me that you are not a teacher of math, chemistry, physics or anything else related to computer programming. That a student could not figure this out is...well...understandable. That a teacher could not is depressing and leaves me in fear of competent people producing wealth in this country in my old age when I need it.

As someone pointed out, in general in the C family this is undefined behavior, as is any expression which comtains a variable that is autoincremented twice. If further runs contrary to good idiomatic practice in these languages where the purpose of this idiom is to write this in the form:

 while((x++)<3) {
        System.out.println(x);
    }

or at worst:

 while(x<3) {
        x++;
        System.out.println(x);
    }

which is the whole point of autoincrementing.

My knowledge of Java is not as great that of C so the behavior may be better defined in Java but a brief reading shows this is ambiguous. It reads "Assign to x the value of X++" which then reads "assign to x the value (old)x and increment X". Where it is ambiguous in C. It can be read as "assign to x the value (old)x" then increment x, or it can be read as "increment x" then assign to "x the value of (old) x". apparently the Java standard specifies the second way or your Java compiler/JVM does it the second way.

I am not a Java language lawyer, but even if it is well defined (in Java) it is poorly constructed.

HandyGandy
Maybe you have a point with your first paragraph - I know too little about the subject to judge that. But it still comes across as very condescending and arrogant. To me, the ability to admit ignorance on a certain topic, and ask about it, a sign of great teacher material.
Pekka
I agree, you can be a good teacher without being born with a mastery of the entire JLS spec. Worse, this really doesn't answer the question. @Handy, you didn't even bother figuring out whether it was well-defined in Java before answering.
Matthew Flaschen
A: 
 x = x++; (increment is overriden by = )

because of above statement x never reaches 3;

Praveen Prasad
A: 

I wonder if there's anything in the Java spec that precisely defines the behavior of this. (The obviously implication of that statement being that I'm too lazy to check.)

Note from Tom's bytecode, the key lines are 7, 8 and 11. Line 7 loads x into the computation stack. Line 8 increments x. Line 11 stores the value from the stack back to x. In normal cases where you are not assigning values back to themselves, I don't think there would be any reason why you couldn't load, store, then increment. You would get the same result.

Like, suppose you had a more normal case where you wrote something like: z=(x++)+(y++);

Whether it said (pseudocode to skip technicalities)

load x
increment x
add y
increment y
store x+y to z

or

load x
add y
store x+y to z
increment x
increment y

should be irrelevant. Either implementation should be valid, I would think.

I'd be extremely cautious about writing code that depends on this behavior. It looks very implementation-dependent, between-the-cracks-in-the-specs to me. The only time it would make a difference is if you did something crazy, like the example here, or if you had two threads running and were dependent on the order of evaluation within the expression.

Jay
+1  A: 

When the ++ is on the rhs, the result is returned before the number is incremented. Change to ++x and it would have been fine. Java would have optimised this to perform a single operation (the assignment of x to x) rather than the increment.

Steven
+4  A: 

Youdon't really need the machine code to understand what's happending.
According the definitions:

1- Assignment operator evaluates the right-hand side expression, and stores it in a temporary variable.
1.1- Current value of x is copied into this temporary variable
1.2- x is incremented now.
2- The temporary variable is then copied into the left-hand side of the expression, which is x by chance! So that's why the old value of x is again copied into itself.

Pretty Simple

houman001
A: 

hi all according to Tom Brito.. i have a doubt.. i have tested the coding; the think is line 1: x=x++;, line 2:Console.Writeline(x); according to this statement before execute line 2 line 1 has to completed am i correct? In the line 1 the value of x is assigned or incrementing .. if first x value is assigned then it has to increment before the line 2 to execute... so my doubt is how zero is printing all the ways it has to increment before to move next.. my tested answer is zero

saj
A: 

I think because in Java ++ has a higher precedence than = (assignment)...Does it? Look at http://www.cs.uwf.edu/~eelsheik/cop2253/resources/op_precedence.html...

The same way if you write x=x+1...+ has a higher precedence than = (assignment)

cubob
It's not a question of precedence. `++` has higher precedence than `=` in C and C++ too, but the statement is undefined.
Matthew Flaschen
A: 

Before increment the value by one , value is assigned to the variable.

kumara
A: 

The x++ expression evaluates to x. The ++ part affect the value after the evaluation, not after the statement. so x = x++ is effectively translated into

int y = x; // evaluation
x = x + 1; // increment part
x = y; // assignment
tia
A: 

Its happen because its post incremented, it means that the variable is incremented after the expression is evaluated.

int x = 9; int y = x++;

x is now 10, but y is 9, the value of x before it was incremented.

See more at: http://cplus.about.com/od/glossar1/g/postincdefn.htm

BrunoBrito
Your `x`/`y` example is different from the real code, and the difference is relevant. Your link doesn't even mention Java. For two of the languages it *does* mention, the statement in the question is undefined.
Matthew Flaschen
+2  A: 

Answer is pretty straightforward, it is to do with the order things are evaluated. x++ returns the value x then increments x.

Consequently, the value of the expression x++ is 0. So you are assigning x=0 each time in the loop. Certainly x++ increments this value but that happens before the assignment.

Mike Jones
A: 

Well as far as I can see, the error occurs, due to the assignment overriding the incremented value, with the value prior to incrementation, i.e. it undoes the increment.

Specifically, the "x++" expression, has the value of 'x' prior to increment as opposed to "++x" which has the value of 'x' after incrementation.

If you are interested in investigating the bytecode, we will take a look at the three lines in question:

 7:   iload_1
 8:   iinc    1, 1
11:  istore_1

7: iload_1 # Will put the value of the 2nd local variable on the stack
8: iinc 1,1 # will increment the 2nd local variable with 1, note that it leaves the stack untouched!
9: istore_1 # Will pop the top of stack and save the value of this element to the 2nd local variable
(You can read the effects of each JVM instruction here)

This is why the above code will loop indefinitely, whereas the version with ++x will not. The bytecode for ++x should look quite different, as far as I remember from the 1.3 Java compiler I wrote a little over a year ago, the bytecode should go something like this:

iinc 1,1
iload_1
istore_1

So just swapping the two first lines, changes the semantics so that the value left on the top of stack, after the increment (i.e. the 'value' of the expression) is the value after the increment.

micdah
+1  A: 

One thing that is kinda funny in Eclipse is that if you test your code:

public class Test {

    public static void main(String[] args) {
        int x = 0;
        while(x<3) {
            x = x++;
            System.out.println(x);
        }
    }

}

which produces the infinite loop, you get no warnings in Eclipse. However, change to ++x;

public class Test {

    public static void main(String[] args) {
        int x = 0;
        while(x<3) {
            x = ++x;
            System.out.println(x);
        }
    }

}

which actually works, and produces the desired result, and Eclipse gives a warning that the assignment to variable x has no effect.

In my opinion, it should have given that error message to the x++ example.

Shervin
well, the first one has an effect of change to 1 and later to 0. The second one increments x and the assignment to itself has no effect. But, yes, it's funny.. :)
Tom Brito
Yes thats right. Basically means x = x, thus you are assigning the same value to it self.
Shervin