Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site utcsri.UUCP Path: utzoo!utcsri!greg From: greg@utcsri.UUCP (Gregory Smith) Newsgroups: comp.lang.c Subject: Re: foo.text[0] Was: Auto variable with sizeof == 0 Message-ID: <4157@utcsri.UUCP> Date: Tue, 17-Feb-87 13:07:38 EST Article-I.D.: utcsri.4157 Posted: Tue Feb 17 13:07:38 1987 Date-Received: Tue, 17-Feb-87 21:46:59 EST References: <4114@brl-adm.ARPA> <4053@utcsri.UUCP> <159@batcomputer.tn.cornell.edu> <626@vu-vlsi.UUCP> Reply-To: greg@utcsri.UUCP (Gregory Smith) Organization: CSRI, University of Toronto Lines: 58 Summary: In article <626@vu-vlsi.UUCP> colin@vu-vlsi.UUCP (Colin Kelley) writes: >In article <159@batcomputer.tn.cornell.edu> braner@batcomputer.UUCP (braner) writes: >> >>In the famous "microEMACS" by David Conroy, which has been widely >>utilized and modified, the basic text-line structure looks like this: >> >>typedef struct LINE { >> struct LINE *nextline; >> struct LINE *prevline; >> short size; /* s.b. int! */ >> short used; >> char text[]; /* !!!!!!!!! */ >>} LINE; >Some other people suggested declaring the text field to be char *text, but >I'm surprised no one suggested this: > >Declare the text field to be char text[1], then use > > lineptr = malloc(sizeof(LINE)-1+length); > >Almost all compilers will optimize sizeof(LINE)-1 into a single constant, so >the code generated is likely to be exactly the same as that generated for >the uEmacs example above...[Of course you can cast the argument to (unsigned) >to keep lint happy.] Well, not quite.... the offset of 'text' within the structure is *not* equal to sizeof(LINE)-1, so the above call to malloc is asking for N bytes too many, where N is 3 on a vax and 1 on a 68K or PDP-11. The problem is that the struct will be padded out after the one-byte 'text' array to meet alignment requirements for the pointer fields. 'sizeof(LINE)' includes this padding. This can be fixed by placing a substruct around everything but the 'text[1]' declaration, and taking the size of that struct instead of sizeof(LINE)-1. Or, declare a dummy struct with the same declarations just to get its size (and *comment heavily* or someone will change one and not the other). The use of a dummy struct instead of a substruct would allow you to leave the struct references unchanged. Both of these methods may fail if 'text' is an array of things other than chars - i.e. if padding is required to align 'text' on a more strict boundary than that required by any previous field in the struct. Nobody said it was easy :-). Alternately, change the declaration to text[4] and the malloc call to sizeof(LINE)-4. This is still a little dodgy - the method in the preceding paragraph is better. > >Gnuplot (which we posted a couple weeks ago) uses this technique because it >seemed to be the most portable... Feel like fixing it? > > -Colin Kelley ..{cbmvax,pyrnj,bpa}!vu-vlsi!colin -- ---------------------------------------------------------------------- Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg Have vAX, will hack...