"array" vs. "&array" ?
Chris Torek
chris at mimsy.umd.edu
Sun Dec 24 03:22:41 AEST 1989
In article <571 at mwtech.UUCP> martin at mwtech.UUCP (Martin Weitzel) writes:
>Some days ago I posted a question if it is legal (or makes sense)
>to write a "&" before an array. I received a few responses, some
>mentioned, that an "&" before an array is illegal and/or that the
>compiler simply ignores it.
This is the K&R-1 (`Classic C') interpretation. In K&R-2/ANSI (`New C'),
& before an array name produces a value with a different type.
Given
basetype arr[SIZE]; /* declares arr as `array SIZE of basetype' */
the type of `arr' is `array SIZE of basetype'. In a value context,
such as the right hand side (but not the left side) of an assignment
operator, an object of type `array N of T' degenerates to a value of
type `pointer to T' whose value is the address of the 0'th element
of the object. This is the same in both Classic C and New C. As
the argument of the address-of operator `&', however, there is a
difference. In Classic C, if the argument is an object of type
`array N of T', the `&' is ignored (with a warning), while in New C,
the result is instead a pointer to that object: a value with type
`pointer to array N of T' whose value is the address of the object.
Thus:
arr
produces a value of type `pointer to basetype', value = &arr[0],
but
&arr
produces either a warning (Classic C), or a value of type `pointer
to array SIZE of basetype' (New C).
>To my understanding, the following *is* a type mismatch:
>-----------------------------------------------------------------------
>main()
>{
> char a[10], (*p)[10];
>
> p = a;
>warning: illegal pointer combination, op =
>}
Yes, it is. To make it correct (but require New C):
> p = &a;
Unfortunately, when handed to an Old C compiler, you get:
>warning: & before array or function: ignored
>warning: illegal pointer combination, op =
>And to all of you who want to now, why I might want to do such strange
>things, look at the following:
>-----------------------------------------------------------------------
>main()
>{
> char m[20][10], (*p)[10];
>
> p = m[0];
> /* ^ to "&" or not to "&", that is the question */
In both Classic and New C, this can be expressed as
p = m + 0;
because `m' has type `array 20 of array 10 of char', and hence `m'
in a value context (such as an operand of `+') produces a value of
type `pointer to array 10 of char' whose value is the address of m[0].
In New C, of course, it can also be written
p = &m[0];
since & accepts an object of type `array 10 of char' and produces a
value of type `pointer to array 10 of char' whose value is the address
of that object (m[0]). It is just those darned Classic C compilers
that refuse to recognise this.
> /* do something with (*p)[x] -- a single char
> and have the possibility to increment p to
> point to the next group of 10 char-s */
>}
>-----------------------------------------------------------------------
>or another one:
>-----------------------------------------------------------------------
>char (*foo())[10]
>{
> static char m[20][10] = {
> /* some initialization */
> };
> int i;
> /* do some calculations giving a value to i */
> return m[i];
> /* ^ to "&" or not to "&", that is the question */
>}
Again, `return m + i' is the only solution that works everywhere.
Incidentally, if you have PCC source, you can add `&arr' to your Classic
C compiler (the result is definitely an improvement) merely by *removing*
several lines of code.
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at cs.umd.edu Path: uunet!mimsy!chris
More information about the Comp.lang.c
mailing list