Subject: Re: Question regarding the array of size 0.
To: None <tech-kern@netbsd.org, freebsd-hackers@FreeBSD.ORG>
From: Greg A. Woods <woods@weird.com>
List: tech-kern
Date: 03/30/2001 19:55:49
[ On Friday, March 30, 2001 at 17:03:49 (+0100), Benny Prijono wrote: ]
> Subject: Re: Question regarding the array of size 0.
>
> Lord Isildur wrote:
> > 
> > sine one knows the size of the struct, who need the pointer? just
> > take the displacement.
> > 
> > char* buf; /* some buffer */
> > struct foo{
> > int header;
> > struct funkystruct blah;
> > };
> > 
> > (struct foo*)buf; /*your headers are here */
> > (struct foo*)buf+1; /* and your data is here */
> 
> nice.
> 
> personally, I still prefer buf[0], because I think it's more readable.
> It's clear for the reader that the struct will be allocated larger
> than sizeof(struct foo), while with macro, that's not immediately
> obvious.

Like it or not the "char data[0]" trick has always been just that, a
(bad) trick.

I used it once, when I first learned it, and have shunned it ever since,
though not so violently as to re-write it in code where I encounter it!  ;-)

Personally I find the cast to be extremely readable.  It is, after all,
a common C idiom that all good C programmers must instinctively know how
to interpret anyway.

You can maybe make it more "readable" by doing it slightly differently
too, such as first adding sizeof(struct foo) to a (void *) pointer to
the head of the buffer, which perhaps more clearly indicates that the
buffer was a concatenation of a struct foo and an array of bytes.

What I really don't like about this trick is that it breaks the idiom of
being able to use sizeof(data) on what's clearly a variable declared as
an array type.  If I want to have an arbitrary collection of bytes
that's of variable length then I don't want to represent it as an array
but rather as a pointer so some storage space and a separate variable to
record its allocated length (and perhaps its real length if the buffer
the pointer points to is re-used but not re-allocated or is itself a
generic array defined to be the maximum length of the data it might
contain).

Of course even using a struct to map data fields onto arbitrary data is
often a questionable (and non-portable) practice too (depending on where
the data comes from, of course)....

Strictly speaking one should always explicitly read each field of the
data (given its specification), perform any necessary conversions, and
then explicitly assign the resulting values to each element in the
struct that will be use to manipulate the data internally.  This is
especially true if the data has an external representation.

-- 
							Greg A. Woods

+1 416 218-0098      VE3TCP      <gwoods@acm.org>      <robohack!woods>
Planix, Inc. <woods@planix.com>; Secrets of the Weird <woods@weird.com>