Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!samsung!uakari.primate.wisc.edu!uflorida!novavax!twwells!bill From: bill@twwells.com (T. William Wells) Newsgroups: comp.lang.c Subject: Re: Zero Length Arrays Allowed in C Standard? Message-ID: <1989Dec14.182113.5398@twwells.com> Date: 14 Dec 89 18:21:13 GMT References: <2298@jato.Jpl.Nasa.Gov> <11715@smoke.BRL.MIL> <480@codonics.COM> <1989Dec2.210042.12668@twwells.com> <8129@cg-atla.UUCP> <1989Dec12.110042.29290@gdt.bath.ac.uk> Organization: None, Ft. Lauderdale, FL Lines: 76 In article <1989Dec12.110042.29290@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes: : One reason I haven't seen given yet is to provide a marker for the end : of an entity. I could use such a beast (more or less) as follows : (example slightly simplified)... : : struct fred { : struct fred * last; : struct fred * next; : long offset; : int thing; : ... bunch of more data stuff : char end_marker[0]; /* MUST BE LAST IN STRUCTURE */ : }; : : .... : : bzero (&fred.offset, &fred.end_marker - &fred.offset); The above is missing some casts. And it can be done as well with the following: bzero((char *)&fred.offset, sizeof(fred) - ((char *)&fred.offset - (char *)&fred)); which does not need the end_marker. This being as ugly as it is, I might just code it as: tmp1 = fred.last; tmp2 = fred.next; bzero(&fred, sizeof(fred)); fred.last = tmp1; fred.next = tmp2; I would certainly do so for exactly one element to be saved. Here's another solution; it too is a bit ugly, but hides the ugliness in the structure definition: struct fred { struct fred * fred_last; struct fred * fred_next; struct { long _fred_offset; int _fred_thing; ... bunch of more data stuff } fred_stuff; }; #define fred_offset fred_stuff._fred_offset #define fred_thing fred_stuff._fred_thing ... bzero((char *)&fred.fred_stuff, sizeof(fred.fred_stuff)); This method leads to many headaches unless you make it a practice to use structure prefixes or some other method of insuring uniqueness of names. On the other hand, it has the advantage that it will likely generate slightly better code than any of the other methods. the first two methods, for example, are very likely to generate several extra instructions to compute the amount of space to clear. : This is quicker than : zeroing each item in the struct separately, and I don't have to worry : about possible padding -- where I would if I tried to work out the size : of the bzero from the sizes of the data items in the region I want to : zap. Warning: null pointers and floating point zeros are *not* necessarily represented by bit patterns of all zero bits. --- Bill { uunet | novavax | ankh | sunvice } !twwells!bill bill@twwells.com