But how do we know when an array is legal?
The same way you know when anything is legal: the language
definition says what can and cannot be done with each type.
since an array is treatd as an array by "sizeof", then I guess
it is legal to have an array for "sizeof".
Right.
As Victor has pointed out, an array's name is always
regarded as a pointer except when it is used in 'sizeof' or 'typeid',
or as a template argument, or as an initialiser of a reference of the
array type.
I'm not sure Victor really knows the language. Some of his
posts seem to show great knowledge, and others contain blatent
misconceptions. In this case: an array's name is *never*
regardes as a pointer. *Never*, *ever*. An array's name is the
name of an array. When used in an expression, it has type
array[] of X. Always. Without exception.
Of course, C++ is noted for its lack of type safety, and it's
lossy conversions. Try something like:
double d = 3.14159 ;
std::string s ;
s = d ;
for example. Or for more fun:
int i = 0 ;
int const c = 0 ;
std::string s ;
s += i ;
s += c ;
The first is---surprisingly---fully defined and legal, although
it probably doesn't do what one might expect. (Actually, any
reasonable person would expect it to be illegal.) The second
has undefined behavior, and will generally result in a core
dump.
The problem isn't that d doesn't have type double, or that i or
c don't have type int. The problem is that C++ is just full of
unexpected and unintuitive implicit conversions. One of those
unexpected, unintuitive conversions is that an array implicitly
converts to a pointer. And in this case, two additional
"defects" in the language add to the conversion. The first is
that there are really very few things you can legally do with an
array---even indexation isn't legal on an array (but it is on a
pointer!). Which means that the implicit conversion occurs a
lot more often than one might like. The second is that
functions cannot have array types as parameters. If the
declaration of the parameter looks like an array, the compiler
automatically converts it into a pointer. Thus:
void f( int array[10] ) ;
declares a function which takes a pointer to an int as argument
(and not an array!), and the name array, within the function, is
not the name of an array, but of a pointer.
Therefore, it seems arrays are illegal for most of the
situations. Under what circumstances are arrays illegal?
I think you're approaching the problem backwards. C++ defines a
set of operators. For each operator, it defines what types are
legal as operands. Unless a type is defined as legal for a
specific operand, it is illegal.
It's one of the first things you have to learn, however. In any
statically typed language.
Do you mean an array of doubles is converted to a pointer pointing to
chars?
No. Doubles are converted to chars. Arrays of doubles are
arrays of doubles.