top | item 35430976

(no title)

lvkv | 2 years ago

I’ve always thought of the array index operator:

  a[index]
as syntactic sugar for the pointer arithmetic:

  *(a + index)
From this point of view, the existence of a “backwards” index operator makes sense; the arithmetic evaluates to the same address.

discuss

order

JTyQZSnP3cQGa8B|2 years ago

I haven't used pointer arithmetic for a long time but the "value" of the index depends on the type, doesn't it? For a char[], it's (a + index), but for an int[] it should be (a + 4*index), or (a + sizeof(type)*index).

I have never understood how the compiler is supposed to know that it's (a + 4*index) and not (index + 4*a) which gives different results. Maybe it's based on the type itself and the computation is done by multiplying the "integral" index with it's size, and adding the "pointer" if there is one.

But even this can give wrong values if you're on an embedded platform where you can store your pointers as integers, size_t, or simple defines without a type.

If anyone knows where I can find the explanation in the standard, I've been wondering about it for at least 20 years...

Edit: it seems that a simple example gives the solution: (void*)[void*] is invalid, and int[int] is invalid too, therefore the compiler will get the pointer as the address, and the integral type as the index. I feel stupid for not testing this earlier.

FreeFull|2 years ago

When you do `*(pointer + 1)`, it'll actually increment the address of the pointer by `sizeof(*pointer)`, so it indeed works the same as indexing `pointer[1]`

addaon|2 years ago

The key point of the article here is that this is no longer strict syntactic sugar in C++ as of C++17. The addition operator, like many operators and all function calls, does not specify the order that its arguments are evaluated. In C, and in C++ prior to C++14, neither did the indexing operator; but as of C++17, the order is fully defined (`a` first in `a[i]`).

leni536|2 years ago

Apart from sequencing rules, a[i] may also differ in value category. If one of the operands is an array rvalue then the result is also rvalue. *(a + i) can't propagate value category this way, dereferencing always produces an lvalue.

mhh__|2 years ago

That's exactly what it is in C