Path: utzoo!attcan!uunet!cs.utexas.edu!mailrus!ncar!ico!ism780c!haddock!karl From: karl@haddock.ima.isc.com (Karl Heuer) Newsgroups: comp.lang.c Subject: Re: extern char *foo vs. extern char foo[] Keywords: by reference, by value, arrays Message-ID: <16804@haddock.ima.isc.com> Date: 6 Jun 90 15:47:01 GMT References: <1990May30.001219.23564@uunet!unhd> <6263@wolfen.cc.uow.oz> <16788@haddock.ima.isc.com> <6273@wolfen.cc.uow.oz> Reply-To: karl@haddock.ima.isc.com (Karl Heuer) Organization: Interactive Systems, Cambridge, MA 02138-5302 Lines: 43 In article <6273@wolfen.cc.uow.oz> pejn@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@ima.ima.isc.com or harvard!ima!karl), The Walking Lint --------cut here-------- #include #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; }