extern char *foo vs. extern char foo[]

Karl Heuer karl at haddock.ima.isc.com
Thu Jun 7 01:47:01 AEST 1990


In article <6273 at wolfen.cc.uow.oz> pejn at wolfen.cc.uow.edu.au (Paul Nulsen) writes:
>If the syntax of C was entirely consistent an [array] `a' in a function
>argument would push the entire array onto the stack.

Yes.  I recently discussed this proposed extension here.

>You have produced yet another illustration of the confusion caused by the
>handling of arrays.  C compilers will ignore the & in f(&a).

This is true only in Classic C, and only for certain compilers.  (Technically
it was illegal to apply `&' to an array, but these compilers would treat it as
a warning only.)

>This is because, within the scope of the array definition, there is no data
>location where the address of a is kept.

No, it's because there are a couple of lines in the compiler source that go to
extra trouble to forbid the construct.  There's no logical reason not to allow
it; ANSI compilers *must* allow it; and it can be fixed in pcc by simply
deleting those two lines in the compiler source.

Note that if `a' has type `int [3]', then `&a' has type `int (*)[3]' (pointer
to array), whereas `&a[0]' (the value to which the expression `a' decays when
used in an rvalue context) has type `int *' (pointer to int).  Part of the
confusion here is that it's very common for someone to say `pointer to array'
when they really mean `pointer to element of array'.  (Chris Torek uses
`pointer *at* array' for this latter construct; I prefer `pointer *into*
array').

The only sense in which `a' and `&a' are the same is that they will compare
equal if they are converted to a common type.  (This is also true of `&s' and
`&s.firstmember' for a struct `s'.)  To demonstrate that they are not
equivalent, try the enclosed program.

Karl W. Z. Heuer (karl at ima.ima.isc.com or harvard!ima!karl), The Walking Lint
--------cut here--------
#include <stdio.h>
#define p(x) printf("%lu %lu\n", (unsigned long)x, (unsigned long)(x+1))
int main() {
    int a[3][5];
    p(a); p(a[0]); p(&a[0]); p(&a[0][0]);
    return 0;
}



More information about the Comp.lang.c mailing list