Zero Length Arrays Allowed in C Standard?

T. William Wells bill at twwells.com
Tue Dec 5 22:25:53 AEST 1989


In article <8129 at cg-atla.UUCP> fredex at cg-atla.UUCP (Fred Smith) writes:
: In article <1989Dec2.210042.12668 at twwells.com> bill at twwells.com (T. William Wells) writes:
: >In article <480 at codonics.COM> bret at codonics.com (Bret Orsburn) writes:
: >: >No; Standard C does not support zero-sized objects.
:
: Excuse me, but I must ask a stupid question. Why the !@#$ would anyone even want
: to declare an array of zero size ???? Isn't that rather similar to a pointer
: to the same type of object??  If so, what is wrong with declaring a pointer
: rather than an empty array ??
:
: I don't want to get flamed for this questin, but I would like an answer from one
: of the gurus (Doug Gwyn, Chris Torek, Henry Spencer, etc.)!

Well, I don't know if you think of me as a guru, but here goes:

Consider a symbol table that is used to store strings. You could
declare a member of it as:

	typedef struct SYMTAB {
		struct SYMTAB *sym_next;
		int     sym_type;
		char    *sym_text;
	} SYMTAB;

This has the drawback that one needs two allocates for the
structure and there is a pointer that really is not needed. The
"ideal" solution would be to stick the string right where the
pointer is.

But how do you declare it? Char sym_next[MAX_SYM];? Not only does
this waste space (we'd expect most strings are much shorter than
MAX_SYM), but it may be the case that there *is* no maximum
symbol length and one does not want to impose one. So that is out.

Here's another: define it as char sym_next[1]; and cheat. By
cheat, I mean to allocate the structure with something like:

	sp = (SYMTAB *)malloc(sizeof(SYMTAB) + strlen(text));

(There's a +1 for the null character and -1 for the 1 in the
structure which cancel.)

This still can waste memory, because of padding in the size of
SYMTAB. Moreover, some systems might take that [1] declaration
seriously and give you an error when you access something beyond
the first element of the string. The kind that immediately comes
to mind is debugging interpreters: these, one hopes, will check
for accessing outside the bounds of an array.

In ANSI C, one could make the declaration:

	sp = (SYMTAB *)malloc(offsetof(SYMTAB, sym_text) + strlen(text) + 1);

which eliminates the potential waste due to padding.

A better solution would be to declare the structure with char
sym_text[0]; The compiler would then forbid taking the size of the
structure (it being undefined), but the compiler would know that
accesses beyond the end of the structure are intended. You'd use
a malloc like the second one to allocate such a structure.

Here's another example. Suppose you want an array to represent
all of data memory, perhaps for an OS. You'll arrange that the
linker will put this at the start of data but you don't want to
declare a size since you don't want the compiler (or the reader,
for that matter) to believe that there is a fixed amount of memory
in your machine. This is different from an extern, in that it is a
definition, not just a declaration. You'd declare it as char
Memory[0];

However, since zero sized objects haven't been sanctified, and
have not been all that available anyway, this is not portable
practice.

---
Bill                    { uunet | novavax | ankh | sunvice } !twwells!bill
bill at twwells.com



More information about the Comp.lang.c mailing list