5

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
Zeta.Investigator
  • 911
  • 2
  • 14
  • 31

6 Answers6

6

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++

Krzysztof Cichocki
  • 6,294
  • 1
  • 16
  • 32
4

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:

  1. You read j = 0
  2. You read j = 0 again
  3. You compute j = j + 1
  4. However, now you compute j = 0 + 0 and override that value

So 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.

Ori Lentz
  • 3,668
  • 6
  • 22
  • 28
3

The issue occurs because 'j++' which if used inside a statement works in the following format -

  1. First the value of j is used inside the statement
  2. Then the value of j is increased.

In your case, when you do j += j++ what happens is -

  1. First the value of 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) .
  2. The incremented value of j is assigned to j , that is j now becomes 1.
  3. The value computed from Step 1 , which is 0 is assigned to j , hence j becomes 0 again.
Anand S Kumar
  • 88,551
  • 18
  • 188
  • 176
2

What does a post-increment operator do? Increment after the operation is completed.

Now j += j++;

Here j is 0 when it is added to j. so 0 += 0 will be a 0.

The value is over-rided so j stays 0 forever.

Let's try with the pre-increment now.

j += ++j;

Output:

i = 0 >> 1 // 0 + 1
i = 1 >> 3 // 1 + 2
i = 2 >> 7 // 3 + 4
i = 3 >> 15
i = 4 >> 31
i = 5 >> 63
i = 6 >> 127
i = 7 >> 255
i = 8 >> 511
i = 9 >> 1023

makes sense?

Uma Kanth
  • 5,659
  • 2
  • 20
  • 41
1

With +=, per JLS§15.26.2:

  1. The left-hand side is evaluated and produces a reference to a variable.

  2. The then-current value of that variable is determined.

  3. The right hand side is evaluated. j++ first gets the value of j (0), then increments it. The result of j++ is the value before the increment, which is 0.

  4. The result is added to the value determined in Step 2 (0) and assigned to the variable determined in Step 1 (j).

So since we end up assigning 0 to j every time, despite the post-increment, the ultimate result is 0.

Here's the spec's actual language:

If the left-hand operand expression is not an array access expression, then:

  • First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.

  • Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

  • Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

  • Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

The problem is here

j += j++;

At the begining, j = 0, then j++ means j will increment in the next iteration. But, before the next iteration, you are assigning the 0 into j. So j re assigned to 0.

mazhar islam
  • 5,561
  • 3
  • 20
  • 41