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;
}

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 incrementednums 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 exceptionThe 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.
See more on this question at Stackoverflow