In early C it was decided to represent the size of an array as part of its type, available via the sizeof
operator. C++ has to be backward compatible with that. There's much wrong with C++ arrays, but having size as part of the type is not one of the wrong things.
Regarding
” pointer has the same function with array, like a[4]
, a
can be both pointer and array
no, this is just an implicit conversion, from array expression to pointer to first item of that array.
A weird as it sounds, C++ does not provide indexing of built-in arrays. There's indexing for pointers, and p[i]
just means *(p+i)
by definition, so you can also write that as *(i+p)
and hence as i[p]
. And thus also i[a]
, because it's really the pointer that's indexed. Weird indeed.
The implicit conversion, called a “decay”, loses information, and is one of the things that are wrong about C++ arrays.
The indexing of pointers is a second thing that's wrong (even if it makes a lot of sense at the assembly language and machine code level).
But it needs to continue to be that way for backward compatibility.
Why array decay is Bad™: this causes an array of T
to often be represented by simply a pointer to T
.
You can't see from such a pointer (e.g. as a formal argument) whether it points to a single T
object or to the first item of an array of T
.
But much worse, if T
has a derived class TD
, where sizeof(TD) > sizeof(T)
, and you form an array of TD
, then you can pass that array to a formal argument that's pointer to T
– because that array of TD
decays to pointer to TD
which converts implicitly to pointer to T
. Now using that pointer to T
as an array yields incorrect address computations, due to incorrect size assumption for the array items. And bang crash (if you're lucky), or perhaps just incorrect results (if you're not so lucky).