[net.lang.c] sizeof and array parameters

Craig Partridge <craig@loki.ARPA> (12/27/84)

    I don't remember seeing this precise topic discussed,  if it
has, someone please enlighten me.

    I was trying to be overly fancy recently and wrote a function that
looked roughly like this (though somewhat more complex):

#define ARRAYSIZE 4

readarray(fd,a)
int fd;
int a[ARRAYSIZE];
{
    read(fd,a,sizeof(a));
}

It failed to work, because sizeof(a) was 4 (the size of a pointer)
instead of 16 (4 positions of ints of size 4).  (This is with the
Berkeley and SUN compilers).

    Now I know why sizeof(a) returned 4 --- "a" is actually a pointer to
int, and that is how it is represented in readarray, and indeed, I caught
this bug reasonably quickly.   However, the more I think about it, the
more I feel that sizeof should have returned 16.  K&R never
explicitly covers this issue, in section 7.2 all they say is that
sizeof an array yields the total number of bytes in the array.
The question of course, is whether one should view paramter "a" as
an array, or just a pointer.  My view is that it is an array, and
should be treated as such.

    My justification for this view is simply, that since it has a dimension
there is no justification for semantically treating "a" as if it were simply
a pointer to integer.  Obviously the representation is still a pointer
to integer, but the major justification for "int a[]" being equivalent
to "int *a" is simply that we don't know the true size of "a".  Since
we do know the size of the array "a" refers to (or think we do, and lint
could tell us if the sizes of the parameters actually passed were off),
why shouldn't sizeof reflect that information?

    Please respond to me directly, and I'll summarize.

Craig Partridge
craig@bbn-loki
{wjh12,decvax,ihnp4}!bbncca!craig

jsdy@SEISMO.ARPA (12/28/84)

> #define ARRAYSIZE 4
> 
> readarray(fd,a)
>  int fd;
>  int a[ARRAYSIZE];
> {
>     read(fd,a,sizeof(a));
> }
>                        ... sizeof(a) was 4 (the size of a pointer) ...
>  ... I feel that sizeof should have returned 16.  ...
> The question of course, is whether one should view paramter "a" as
> an array, or just a pointer.  My view is that it is an array, and
> should be treated as such.  ...  since it has a dimension
> there is no justification for semantically treating "a" as if it were simply
> a pointer to integer.  Obviously the representation is still a pointer
> to integer, but the major justification for "int a[]" being equivalent
> to "int *a" is simply that we don't know the true size of "a".  ...

There's some justification to this.  But it is generally understood
(K&R 5.3 par.9, e.g.) that the parameter can be handled as either a
pointer or an array.  Everything you can do to an array, you can do
to a pointer, but not vice versa -- so parameters are in fact imple-
mented as pointers.  (E.g., ++a is legal even above.)  It doesn't
matter what convenient legal fiction you are using at the moment.
The compiler must recognise 'a' as a pointer:  if it treats it as
an array, you will be climbing the stack instead of dereferencing
the pointer.

Joe Yao		(UUCP!seismo!hadron!jsdy / hadron!jsdy@seismo.ARPA)

taso@munnari.OZ (Taso Hatzi) (12/28/84)

In article <6794@brl-tgr.ARPA> Craig Partridge <craig@loki.ARPA> writes:


>
>#define ARRAYSIZE 4
>
>readarray(fd,a)
>int fd;
>int a[ARRAYSIZE];
>{
>    read(fd,a,sizeof(a));
>}
>

Might I suggest that what you really meant was:

#define ARRAYSIZE 4

readarray(fd, a)
int fd;
int (*a)[ARRAYSIZE];
{
    read(fd, a, sizeof(*a));
}


You should find the last two paragraphs of K & R p94 informative. 

I think it's unfortunate that 

f(x)            
int x[N];
{
}

is a legitimate way of declaring an array argument. It has made it practically
impossible to allow for arrays to be passed by value. On the other hand, given
that arrays will never be passed by value, it does make array references from
inside the function look tidier.

mccaugh@uiucdcs.UUCP (12/29/84)

 It seems the C compiler in use may be at fault; on p.97 of "C: A Reference
 Manual", Harbison & Steele state: "...when the array identifier is used as
 an operand of the SIZEOF operator...SIZEOF returns the size  of the entire
 array, not the size of a pointer to the first array element."  (Also, read
 the bottom of p.99)

 --uiucmsl!mccaugh