Can anyone explain this behavior to me?
First, I thought the answer would be 511 + 512 (if j += j++ would mean j = j + (j+1))
How can I justify the answer zero?
public class Test
{
public static void main(String[] args)
{
int i = 0;
int j = 0;
for (i = 0, j = 0; i < 10; i++)
{
j += j++;
System.out.println("i = " + i + " >> " + j);
}
System.out.println(j);
}
}
> java Test
i = 0 >> 0
i = 1 >> 0
i = 2 >> 0
i = 3 >> 0
i = 4 >> 0
i = 5 >> 0
i = 6 >> 0
i = 7 >> 0
i = 8 >> 0
i = 9 >> 0
0
Because, the j++
, means increment after evaluation, and j+=x
means j=j+x
so the j
becomes j+1
after evaluating j=j+j
which is zero( the addition result is 0) after computation of this addition, the j is incremented by j++, but after that the addition result overrides the incremented j value by its value 0.
look at this, let assume j=0;
j += j++
the j++
incrementation will be executed after reading the j
value, which is 0
for now.
so it translates into:
1) read the first value for add operation - the value of j is 0 so we have add(0, ?)
2) read the second value for add operation `j++` is first evaluated to 0
so we have now add(0,0),
then j is incremented by 1, but it has this value for a very short time:
3) execute the add(0,0) operation, the result is 0 and overrides the incrementation done in previous setep.
4) finally the j is 0
So the j becomes a 1 for a very short time in this case, but is overridden very quickly after that.
The conclusion is that mathematically j += j++;
finally becomes only j = j + j;
in your for loop this situation repeats every single loop execution, initially the j is 0, so it stays like that forever with blinking to one for a very short time in each loop run.
Maybe you could make the j volatile and then read it in a loop by other thread during evaluation of this j += j++;
. The reading thread could probably see that j becomes 1 for a moment, but this is indeterministic, in my case I see this happening using this simple test program:
public class IncrementationTest {
public static void main(String[] args) {
new IncrementationTest().start();
}
private volatile int j;
private void start() {
new Thread() {
@Override
public void run() {
while (true) {
System.out.println(j);
}
}
}.start();
while (true) {
j += j++;
}
}
}
the output is:
...
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
...
On my machine it seems to happpen pretty often to have the luck of reading the intermediate 1 for the evaluation of j += j++
Because when you do a = b + c
you first read b
and c
and then calculate the values.
Also, j++
means returns the current value of j and then increment it by one.
In your case, since you do j = j + j++
you first read j
, then you read j
again and returns the value of j
. Let's do an example with the first iteration:
j = j + 1
j = 0 + 0
and override that valueSo by the end of the iteration, j
's value hasn't changed. It's still 0. That's true for every iteration which is why the value of j
never changes.
The issue occurs because 'j++' which if used inside a statement works in the following format -
j
is used inside the statementj
is increased.In your case, when you do j += j++
what happens is -
j
is used inside the statement , is used in the statement, hence j++
returns 0
to be used in the statement, and we have computed 0 + 0
to be assigned to j
(not yet assigned) .j
is assigned to j
, that is j
now becomes 1
.j
, hence j
becomes 0
again.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With