1

I came across this line of code in java in nutshell book and I would like to know how compiler divide this code

a[i++] += 2;
a[i++] = a[i++] + 2;
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
  • I understand that j=i++; will evaluate to j=i ; and i=i+1; What about these two lines – Mustafa Mahmod Aug 04 '19 at 19:29
  • 1
    Also, depending on the exact version of java you are running, [this question](https://stackoverflow.com/questions/50683786/why-does-arrayidx-a-increase-idx-once-in-java-8-but-twice-in-java-9-and-1) (and [this bug](https://bugs.openjdk.java.net/browse/JDK-8204322)) might be of importance – Turing85 Aug 04 '19 at 19:30

1 Answers1

3

15.26.1. Simple Assignment Operator =

If the left-hand operand is an array access expression (§15.10.3), possibly enclosed in one or more pairs of parentheses, then:

First, the array reference subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the index subexpression (of the left-hand operand array access expression) and the right-hand operand are not evaluated and no assignment occurs.

Otherwise, the index subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and the right-hand operand is not evaluated and no assignment occurs.

https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.26.1

I assume the order of evaluation should be as follows

a[i++] = a[i++] + 2;
  ^      ^ ^
  1      3 2
         ----------
             ^
             4
------
  ^
  5
--------------------
         ^
         6

We can prove it by running this snippet

int[] a = {0, 10, 0, 0};
int i = 0;
a[i++] = a[i++] + 2;

System.out.println(Arrays.toString(a)); // [12, 10, 0, 0]
System.out.println(i);                  // 2
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
  • 2
    A (perhaps) interesting thing to point out is that both of the `i++`s are evaluated before either of the array dereferences occur. If you define `int[] a = null;`, wrap the "interesting" line in a try/catch (to catch the NPE), printing `i` after results in 2. A frankly bizarre consequence is that you can assign the array *after* you have referenced it on the LHS: `a[i++] = (a = new int[2])[i++];`, the `a` used on the LHS is the newly-assigned one. – Andy Turner Aug 04 '19 at 21:52