Zero Length Arrays Allowed in C Standard?

Spencer Garrett srg at quick.COM
Thu Dec 7 19:08:17 AEST 1989


> OK. Thanks to all of you who sent me good answers to my question about
> reasons for zero-length arrays.
> 
> Now I think I understand. In fact, I recall having seen code previously
> which used a zero-length array at the tail end of a structure. I thought
> at the time that it was a HORRIBLE way to write code. I STILL think so.
> Sure, it works (on some implementation!!!!). Sure, its also convenient
> and useful. Does that make it good C?  Does that make it easy to figure
> out when you trip over it for the first time in somebody's undocumented
> piece of code?  NO.

Oh, please.  Zero length arrays are clean, simple, easy to understand,
and easy to implement.  They are by far the most elegant way to deal
with expandable arrays at the end of structures, and this is a very
important problem.

> I think that its convenience is not sufficient reason to insist that
> it should be a part of the language. After all, there are other
> conveniences which are used in certain implementations that are also not
> a part of the language as specified by X3J11, ususally for good reason.

But this "convenience" is in no way implementation specific.  It is
cleanly implementable in any environment which is capable of hosting
C at all.

> One reason that comes to mind is a conflict with the way arrays 
> relate to pointers. For normal arrays, simply mentioning its name
> in a program evaluates to the address of the array. Now what is this
> address??  It is the address of the first element of the array! If
> the thing is declared as zero length, what do you get when you
> mention its address ??  I dunno, haven't tried it yet (I intend to),
> but I bet it makes no sense, whatever it is! Even if it does evaluate
> to some address somewhere, it certainly is not an address at which
> one would dare to store data (without, of course, the use of malloc
> to create some data space there)! I would guess that it is because of this kind
> of sticky issue that the committee chose not to embrace zero-length
> arrays.

Zero-length arrays work *exactly* like arrays *of any other length*.
You'll get exactly the same address no matter what the size.  It's no
accident that the first element past the end of an array is a legal
address.  There's no other clean way to deal with any array.  The only
distinction is that, for zero-length arrays, the 0'th and N'th elements
are at the same address (because N is 0).  Of course you can't store
anything in a zero-length array that has been statically allocated.
That's not what they're for.  You can *always* store N elements in
an array of length N, so what did you expect?

> Sure, it would be nice if everybody's favorite feature (or abuse of the
> language) were specified in the standard. However, the guys onthe committee
> were also trying to make all the pieces fit together in a more-or-less
> logical manner, so as to reduce some of the hidden gotchas, and it seems
> to me that this particular one does have a few hidden gotchas. It certainly
> is easy enough to work around the "lack" of this "feature".

But it's always a work-around, and there are lots of inelegant possibilities.
How would you deal with the following?

	struct blat {
		struct blat    *next;
		int		value;
		char		name[0];
	} *new;
	char *str;

	new = (struct blat *)malloc(sizeof(struct blat) + strlen(str) + 1);
	new->next = ??;
	new->value = ??;
	strcpy(new->name, str);

The "char name[0]" is telling the compiler that a character array is going
to start at that point in the structure, but that sizeof(struct blat)
should not include any of the elements of that array.  You don't want
to leave out the definition of "name" entirely, since you want to have
something to call it as part of the structure, and you need to tell
the compiler its type anyway, so that alignment restrictions can
be dealt with (not all such arrays are character arrays).  If you
declare it "char name[1]" then there's no portable way to get the
size of the header (since you can't predict how much padding may
need to be added).  The best you can do is to throw away that 1 element
you declared just to avoid having to understand the concept of zero.



More information about the Comp.lang.c mailing list