Sorry. I had assumed the use of word 'type' was clear in the context of my
question. But here is a more carefully 'worded' version.
I tend to take wording pretty literally, because often ambiguous wording
reflects a poster's unfamiliarity with the basic concepts--so I can't be
quite sure if the question I think I'm answering is the one really being
asked. I, in fact, often answer the wrong question even when the wording is
/clear/, so I tend to ask for clarification a lot ;-)
int v[3];
int w[3][3];
Granted that v is a variable with certain storage type. But v is also a
variable of type int[3] and w is a of type int[3][3].
OK, I'm already hung up on your wording above. In this case it isn't going
to keep me from answering you subsequent questions, but... what do you mean
by v being "a variable with certain storage type", and "also a variable of
type int[3]" ? Isn't int[3] in fact "a certain storage type"? I'm sorry,
this is a really strange way to phrase whatever it is you're thinking, and
I must admit I haven't a clue as to what you are trying to say. But
hopefully it won't matter, if you understand what's going on below.
void fun1(int v[2]) {}
void fun2(int v[2][3]) {}
void fun3(int v[2][2]) {}
int main() {
int v[3]={};
int w[3][3]={};
Are the empty braces just to force zero-initialization? I didn't even
realize that was legal, until just trying it. Usually I see at least a 0
in there, e.g:
int v[] = {0};
But I guess that's just a matter of style.
fun1(v);
fun2(w);
fun3(w);
}
It is a mystery to me why fun3(w) produces a compile error while the others
don't. For some reason the first dimension of an array is ignored when doing
type checking--as if v had the type int[] and w the type int[][3].
Formal parameters to a function written in the form of 1- or 2-dimensional
arrays actually do behave as you've just described, but they're actually
just pointers. Another way of looking at it: the first dimension of an
array parameter is "syntactic sugar", and is not actually part of the type.
The other dimensions are. In your definition of fun1 above, v has type
"pointer to int". In fun2, v has type "pointer to array of 3 ints". In
fun3, "pointer to array of 2 ints".
So let's look at your calls. In the call to fun1, you pass an array of int;
Arrays of T "decay" to type "pointer to T" when used in most contexts. So
you're actually passing a pointer to int, matching the parameter to fun1
fine.
In the call to fun2, you're passing w, a 2D array of ints with dims 3,3, or
alternatively, an array of 3 arrays of 3 ints. When you pass that to a
function, then, you're actually passing a pointer to an array of 3 ints.
Again a perfect match.
In the call to fun3, you're passing the same array, but this time to a
function expecting a different kind of pointer. Hence the error.
I used
sizeof operator to note that indeed v has the same storage requirement as
type int[2] in the main() which implies that at least here the compiler
acknowledges that v is indeed of type int[2] and not of type int[]. But then
later it treats it as int[] despite the specified type.
Okay, I've lost you again. You've defined v in main() as follows:
int v[3]={};
That's type int[3]; not type int[2], and certainly not int[] -- which isn't
even really a type, and you can test that by trying to compile a line like
this:
cout << "size: " << sizeof(int[]) << endl;
and noting it does not compile. Remember, when used in a formal parameter
declaration, it is really treated as "int *".
You can also check this by noting that fun(int v[3]) and fun(int v[4])
cannot be overloaded (since the compiler sees them as type int[])
which is the same as "int *"...
but the
fun(int v[3][3]) and fun(int v[4][4]) can be overloaded.
Right. Different types.
I realize that you don't need the size of the first dimension of an array
for index computation while you need the rest. But surely this is a
different issue than type checking.
Bzzzt. All but the first dimension of an array parameter are crucial to the
type; hence, crucial to type-/checking/.
-leor