X = x ++ not incremented because ++ is applied after assignment?
From page 280 of the Java SE 6 Programmer Exam, Question 9:
int x = 3;
x = x++;
// x is still 3
In the explanation, we can read that:
The string
x = x++;
does not leavex == 4
if applied++
after . The appointment has happened.
I agree that x
equals 3, I understand post-incrementation.
I disagree with the explanation. I would replace "after" with "before".
I thought it worked like this:
-
x
equals 3. Running -
x++
... I see the post-increment operator as a function:int operator++() { int temp = getX(); setX(temp + 1); return temp; }
So after
x++
executionx
is 4, but the value returned from the expressionx++
is3
. - Now the assignment
=
. Just write returned3
tox
.
So, in my eyes it ++
applied before , it happened. I am wrong?
source to share
... is applied
++
after .
Okay, hold on. This is actually confusing and possibly suggests wrong behavior.
You have an expression & dagger; :
x = ( x++ )
What's going on ( JLS 15.26.1 ):
- The expression on the left side of the assignment
x
is evaluated (to create a variable). - The expression on the right side of the assignment
( x++ )
is evaluated (to get the value). - Right side evaluation:
x
performed after the increment, and the expression evaluates to the old valuex
. - The variable on the left is
x
assigned the value obtained from evaluating the right, which is the old valuex
.
So the post-increment happens before the assignment.
(Hence, as we know, the value x
after the statement is executed is the x = x++;
same as the value x
before the statement is executed, which is 3
.)
So, in my eyes it
++
applied before , it happened. I am wrong?
You're right.
Technically, the way it is specified is that it is evaluated before its result is stored and during the evaluation of the assignment operator . Thus, it can be interpreted as happening before or during the appointment. Not after, so the book feels wrong anyway. x++
x++
Just for that, we can also look at some bytecode:
/* int x = 3; */
iconst_3 // push the constant 3 on to the stack : temp = 3
istore_0 // pop the stack and store in local variable 0 : x = temp
/* x = x++; */
iload_0 // push local variable 0 on to the stack : temp = x
iinc 0 1 // increment local variable 0 by 1 : x = x + 1
istore_0 // pop the stack and store in local variable 0 : x = temp
iinc
happens before istore
.
& dagger ;: The parentheses do not affect the score, they are just for clarity.
source to share
Reaching the official specification:
- postfix c ++ section: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
- assignment statement section: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.1
In terms of assignment, this is a simple assignment, so we fall into case 3:
- First, the left operand is evaluated to create a variable -
x
- no errors -> right operand is evaluated -
x++
- "the value of the right operand is converted to the type of the left variable, undergoes conversion of the set of values โโ(clause 5.1.13) to the corresponding standard (the set of extended exponents is not specified), and the result of the conversion is stored in the variable"
So, in step 2, the postfix operator should be allowed, and then in step 3, x gets its original value again:
call: x = x++;
interframe: LHS is variable 'x'
interframe: RHS caches return value as 3
interframe: x is incremented to 4
interframe: RHS cached value '3' is returned for assignment
interframe: variable x is assigned value 3
call result: x = 3
So, I think you are correct that the book is wrong and it might be worth contacting the authors or publishers to post a fix (or added to the bug page, etc.).
source to share