Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!uunet!twwells!bill From: bill@twwells.com (T. William Wells) Newsgroups: comp.lang.c Subject: Re: Zero Length Arrays Allowed in C Standard? Message-ID: <1989Dec5.112553.24087@twwells.com> Date: 5 Dec 89 11:25:53 GMT References: <2298@jato.Jpl.Nasa.Gov> <11715@smoke.BRL.MIL> <480@codonics.COM> <1989Dec2.210042.12668@twwells.com> <8129@cg-atla.UUCP> Organization: None, Ft. Lauderdale, FL Lines: 77 In article <8129@cg-atla.UUCP> fredex@cg-atla.UUCP (Fred Smith) writes: : In article <1989Dec2.210042.12668@twwells.com> bill@twwells.com (T. William Wells) writes: : >In article <480@codonics.COM> bret@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@twwells.com