Is the postfix increment operator (++) broken in Java?

It has been observed by a lot of people that the behavior of the following code is not what is expected:

int x = 1;
x = x++;
System.out.println(x);

What most people expect the output to be is 2, but instead we get 1, which throws our carbon-based processing units for a loop. Anyone who has worked with proramming languages that borrow syntax from C knows what the postfix increment operator, ++, does: it increments. So why isn't the resulting value of x in the above sequence incremented? Actually, it is - it just doesn't show up that way in the end. This is not a bug; there is a legit reason why...

But before I attempt to explain the observed behavior, let me say a little something about this type of code. IM<HO (translation, In My Less-than Humble Opinion) this is a totally bogus piece of code to ever write. In fact, I've read that its behavior in C is officially undefined. Asking what is the result of such poorly constructed code is sometimes called a stupid question, which I can't disagree with. But sometimes even stupid questions deserve a least a bit of discussion, especially when, as in this case, doing so can remind us of syntactical rules that we tend to take for granted in our everyday use of the language. Not to mention that I've been told that this question comes up on certain certification exams (I'll get to my thoughts on that later).
Anyway, if I came across code like i = i++; I would remove it immediately, and if I knew who wrote it I'd immediately attempt to explain the folly of it to him/her. Actually, "explaining the follly" sounds a lot nicer than what I woud really do to him/her - this kind of thing has no place in production code, period. In fact I'm not the first person to question the unary increment/decrement operators are included in Java at all.

So what about the observed behavior of x = x++ ?
The reason it behaves as observed is because of the interaction between the operator precedence and the odd "return value" of the ++ operator.
The postfix increment happens first (see your favorite copy of the operator precedence chart); but postfix, by definition, returns the previous value of the variable. So that "return value" is not "original x plus one", but instead just "original x" (x, at this point, actually contains the incremented value). This returned value is then assigned to x, which overwrites what the ++ did in the first place. IOW, in the expression x=x++, the incremented value is lost, overwritten by the assignment that happens last.

You can think of ++ as a method like this:

int postfixIncrement() {
    int result = x;
    x = x + 1;
    return result;
}

Then "x=x++" is rewritten as "x = postfixIncrement()" and the result is a little more intuitive.

Another perspective on it:

x = 1;
x = x++;
This translates to the following:

1) x is assigned the value 1.
2) x++ is performed, and its value is returned as x:
2a) x is assigned x+1, IOW x is assigned value 2
2b) Value 1 is returned to the expression.
3) x = (...) is performed:
3a) x is assigned the value from 2b, which is 1

So, after all is said and done, the value assigned to x is 1.

The fact that this is so difficult to explain and unexpected (to the casual or naive reader) is exactly why this kind of code SHOULD NEVER BE WRITTEN - PERIOD. This is not even a legitimate exam question, IMHO - the only thing it really tests is the person's luck to have seen this type of explanation before.

line
All photographs and content is copyright © 2003-2006 Eric Rizzo & Jazmine Rizzo

contact classes office hours about me Go home