foo.text[0] Was: Auto variable with sizeof == 0

Gregory Smith greg at utcsri.UUCP
Wed Feb 18 04:07:38 AEST 1987


In article <626 at vu-vlsi.UUCP> colin at vu-vlsi.UUCP (Colin Kelley) writes:
>In article <159 at batcomputer.tn.cornell.edu> braner at 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...



More information about the Comp.lang.c mailing list