pete posted:
[#3] Except when it is the operand of the sizeof operator or
the unary & operator, or is a string literal used to
initialize an array, an expression that has type ``array of
type'' is converted to an expression with type ``pointer to
type'' that points to the initial element of the array
object and is not an lvalue.
The reason they can put that in the Standard is that they've thought up of
every conceivable place where you can use an array as an array -- there's
only three such places, so it was handy to list them all.
In C++, we treat the array-to-pointer conversion just like any other
implicit conversion (e.g. char to int).
If we have a char:
char k;
It will remain as a char unless it needs to convert. For example:
void TakesAnInt( int r ) {}
int main(void) { char k; TakesAnInt(k); }
Just because a "char" can implicitly convert to an "int" doesn't mean
"char" is any less of a fully-fledged object type.
If we were able to pass arrays by value in C, then they'd have to remove
that paragraph from the Standard (or perhaps add the fourth instance where
you can use an array as an array).
In C++, we have references, and we can pass arrays by reference, so we tend
to look at it from the opposite viewpoint of C programmers.
Instead of thinking:
"When is an array actually an array, instead of being a pointer?"
We think:
"When does the array decay to a pointer?"
The most obvious place where we need to convert from array to pointer is by
the dereference operator:
*array /* You can't dereference an array, so it has
to become a pointer to its first element */
or by block brackets:
array[5] = 2; /* You can't use block-brackets with an array,
so it has to become a pointer to its first
element. */
Or by arithmetic:
array + 3 /* You can't use '+' with an array, so it has to
become a pointer to its first element */
Now that we know that an array will always be an array unless it needs to
convert to a pointer, we can pass arrays by reference:
void SomeFunc( int (&array)[20] )
{
}
int main()
{
int array[20];
SomeFunc( array );
}
The dandy thing about this way of thinking is that it works perfectly for C
aswell.
A char is a char, not an int (but it's more than happy to convert if it
needs to).
An array is an array, not a pointer (but it's more than happy to convert if
it needs to).
As C++ is constantly being developed and expanded upon, it's more
appropriate to state where an array decays to a pointer, rather than where
an array actually stays as an array.
Moral of the story: An array is an array -- not a pointer.
-Tomás