0

I was practicing writing some sorting algorithms and wrote the following code for insertion sort:

public static void insertionSort(int[] nums) { for (int i = 1; i < nums.length; i++) { int idx = i; int val = nums[idx]; while (idx > 0 && val < nums[idx - 1]) { nums[idx--] = nums[idx - 1]; } nums[idx] = val; } } 

The previous code resulted in an index out of bounds exception at -1. My understanding of how nums[idx--] = nums[idx-1] would work is that nums[idx] would be assigned the value at nums[idx-1] and then the -- would reduce idx by one (I thought the whole purpose of having it after the variable was to allow the user to take action/execute assignments with the current value ~before~ incrementing it up or down. However, its seems that once the code checks nums[idx-1] on the left side of the expression, idx-- has already occured, resulting in the pointer hitting -1 at the end of the array. Based on this result, is it safe to say that my initial assumption that the decrementing is not the last executed part of this line, but rather we should assume that the decrementing will occur first if it is to the left of the next usage of the variable?

As a follow-up, does anyone know why is is set up to work this way? This seems counter-intuitive.

For reference, changing the code to the below fixed the issue, which verified that it must be incrementing prior to checking:

public static void insertionSort(int[] nums) { for (int i = 1; i < nums.length; i++) { int idx = i; int val = nums[idx]; while (idx > 0 && val < nums[idx - 1]) { nums[idx] = nums[idx - 1]; idx--; } nums[idx] = val; } } 
2
  • 1
    Or nums[idx--] = nums[idx]; or nums[idx] = nums[--idx]; Commented Jan 10, 2024 at 4:37
  • 2
    Details can be found in the Java Language Specification 15.7. Evaluation Order like "The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated" and specifically for the assignment 15.26.1. Simple Assignment Operator = Commented Jan 10, 2024 at 8:41

2 Answers 2

2

You're using idx multiple times per statement in line:

nums[idx--] = nums[idx - 1]; 

so here's what happens in your code:

  • nums[idx] is evaluated using the current value of idx.
  • idx is then decremented
  • nums[idx - 1] is evaluated using the new, decremented value.

So, if idx was originally 1, nums[idx--] refers to nums[1] in step 1, but nums[idx - 1] refers to nums[0 - 1], which is nums[-1], leading to an ArrayIndexOutOfBoundsException.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for clarifying here - that is what I assumed was happening. I am just surprised that this is the intended behavior as I thought it would make more sense to decrement idx following the execution of the assignment. I guess this is just one of those "that's how it is" nuances of Java. Thanks!
-2

If the LHS is an array access expression, it is evaluated first.

Kindly refer this doc

2 Comments

The LHS is always evaluated first. JLS #15.7.
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.