0

I was working on a leetcode question [1] and noticed something that caught my eye.

When I write a line of code as:

nums[i] = nums[(i++)+count];

I pass all the tests and my answer is accepted. If however I change the same line to:

nums[i++] = nums[i+count];

I get an ArrayOutOfBounds exception. Why is this?

Here is the full code:

public void moveZeroes(int[] nums) {
    int count = 0, i = 0;
    while(i+count < nums.length){
        if(nums[i+count] == 0)
            count++;
        else
            nums[i] = nums[(i++)+count];
    }
    for(;i<nums.length; i++)
        nums[i] = 0;
}

[1] https://leetcode.com/problems/move-zeroes/

2 Answers2

5

The answer lies in JLS 15.26.1. Basically, this is the order of things in the case of

nums[i++] = nums[i+count];
  • nums is evaluated (as part of the left-hand side)
  • i++ is evaluated to find the index; the result is the original value of i, but i is then incremented
  • At this point, we've evaluated which array element we're assigning to
  • nums is evaluated (as part of the right-hand side)
  • i+count is evaluated; note that this uses the already incremented value of i, which is why you're getting an exception
  • We now know which array element we're fetching
  • Fetch the value of that element
  • Assign the value into the LHS element we identified earlier

The important part is that the left operand of the assignment operator is evaluated before the expression on the right operand. So the side-effect while evaluating the array index expression in the left operand affects the evaluation of the right operand.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    For a more complex example (`i = i += (++i + (i += 2 + --i) - ++i)`), see [Incrementor logic](http://stackoverflow.com/q/33120663/5221149). – Andreas Jul 22 '16 at 05:20
0

In the first example, i is being incremented after it is done being used in that iteration.

nums[(i++)+count];

means increment i by one after evaluating the equivalent of nums[(i) + count].

In the second example, i is being incremented before nums[ i +count];.

nums[i++]

means increment i by one after evaluating the equivalent of nums[i].

When the code gets to nums[ i + count];, i has already been incremented. This is results in an ArrayOutOfBounds exception in the case that i + count is equal to nums.length.

Moishe Lipsker
  • 2,974
  • 2
  • 21
  • 29