0

I am reading through the section about pointers and arrays from "The c++ programming language", and I came across something that stumps me.

For every built-in array a and integer j within the range of a, we have:

a[j] == *(&a[0]+j) == *(a+j) == *(j+a) == j[a]

I understand why *(&a[0]+j) means the same as a[j], because &a[0] points to the first element of a and then it's incremented by j.

I also get that *(a+j) and *(j+a) are equal to a[j], a gets implicitly converted from an array to a pointer to the first element of a, and then incremented by j and dereferenced.

But why is a[j] == j[a]? What am I missing?

Heath Raftery
  • 3,643
  • 17
  • 34

1 Answers1

2

Because the subscript operator is commutative. It is simply specified to be so by the language.

You can see the symmetry from the equivalence with the pointer arithmetic expressions, where the addition operator is also commutative:

a[j] == ∗(a+j)
j[a] == ∗(j+a)
∗(a+j) == ∗(j+a)

The language standard (draft) says:

[expr.sub]

... The expression E1[E2] is identical (by definition) to *((E1)+(E2)) ...

[Note: Despite its asymmetric appearance, subscripting is a commutative operation except for sequencing.

Community
  • 1
  • 1
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Thanks, that explains it. I feel rather stupid for not linking the fact that if `j[a] ==∗(j+a) == *(a+j)`, that `a[j]` also equals that. – MassiveAtoms Jun 01 '19 at 23:50
  • if a[j] == j[a], would a[j] produce the same assembly code as j[a] ? I have the feeling that it won't. On IA32, let's assume that EBX has the address for a[0] (i.e. EBX = &a[0], and ESI has the value of j. Besides, let's assume a is an array of 32-bit ints, so a[j] translates to [EBX+4*ESI] but j[a] would translate to [ESI+4*EBX]. Most probably, EBX+4*ESI is not the same value as ESI+4*EBX – mcleod_ideafix Jun 02 '19 at 00:07
  • 1
    @mcleod_ideafix there is no reason for the expressions to translate to the instruction that you suggest. See for example how the two expressions are translated into identical instructions: https://godbolt.org/z/aNsv25 – eerorika Jun 02 '19 at 01:09
  • I see. Regardless of how you write the [] expression, the compiler can detect which one is the actual pointer and which one is the actual offset and therefore, emit the same opcodes for both situations. – mcleod_ideafix Jun 02 '19 at 10:25