[net.lang.c] Block Initialization; structs and sizeof

msb@dciem.UUCP (Mark Brader) (10/10/86)

Suppose that, on your machine, ints are 4 bytes and must be aligned
on multiples of 4 bytes.  Chars, of course, are 1 byte.  Now declare:

	struct str {int i; char c;} arr[2], sca;
	char buf[32];

Now, in arr, each i member must go on a new 4-byte boundary, so there
is 3 bytes of padding after each c member.  So sizeof arr[0] is 8.

The most recent ANSI draft that I've examined specifies that if sizeof is
applied to a structure type, the result is the size of such a structure
including any trailing padding that would be necessary in an array of
such structures.  Therefore sizeof (struct str) is also 8 and, as far as
I know, sizeof sca is also 8.

However, the scalar struct sca is not required to have those 3 bytes
of padding.  This suggests that some compilers may place another
variable, say buf, at ((char *) &sca) + 5.  In this case a construct
such as the "bzero(&p, sizeof(p))" mentioned in Sin-Yaw Wang's article
The problem is that sca, the scalar struct, is NOT required to have
those 3 bytes of padding*.  Thus some compilers may decide to economize
on storage and place another variable, say buf, 5 bytes past the start
of sca.  And then, of course, something like the "bzero(&sca,sizeof sca);"
proposed in Sin-Yaw Wang's article (to which this is a followup) will
overwrite the first 3 elements of buf!

*K&R Appendix A does not speak of trailing padding at all; the most
 recent draft ANSI standard that I've examined does not speak of
 trailing padding in scalar structs.  I mentioned this to Larry Rosler,
 but I have not been able to check a later draft.  Of course, even if
 this is now covered, it doesn't affect current compilers.

ARE there any compilers out that don't always put trailing padding
on structs?  (Note: replies of the form "my compiler does put padding"
should not be posted unless there are a bunch of replies the other way!)

Mark Brader, utzoo!dciem!msb
#define	MSB(type)	(~(((unsigned type)-1)>>1))

msb@dciem.UUCP (Mark Brader) (10/15/86)

Distribution:

I wrote:
>	struct str {int i; char c;} arr[2], sca;
>	char buf;
> The most recent ANSI draft that I've examined specifies that if sizeof is
> applied to a structure type, the result is the size of such a structure
> including any trailing padding that would be necessary in an array of
> such structures. ...

> However, the scalar struct sca is not required to have [the] padding.
> ... Thus some compilers may decide to economize
> on storage and place another variable, say buf, [where it would be] ...

According to mail from Larry Rosler, this has been fixed, and the current
draft reads:

# There may also be unnamed padding at the end of a structure,
# as necessary to achieve the appropriate alignment WERE the
# structure to be a member of an array.  [Emphasis added]

He has suggested that the definition of sizeof be simplified to remove
the "that would be necessary..." part, which is now redundant.

Mark Brader, utzoo!dciem!msb
	"You take the bottle out of the box, take the cotton out of the
	 bottle ... and if they'd just used the box and not used the bottle
	 ... look at this, all these pills would've fitted into the box and
	 they'd have had room for 3 times as much cotton!"   -- Andy Rooney

pedz@bobkat.UUCP (Pedz Thing) (10/16/86)

In article <1971@dciem.UUCP> msb@dciem.UUCP (Mark Brader) says that in
effect (&variable + sizeof(variable) > &nextvariable) is possible.
While I understand his argument and reasoning, I hope that this is not
true.  This would break many things it seems to me.  In particular,
varargs would be a very difficult thing to write since the "nextarg"
(or whatever it is called) would have to know the type of the next
argument in order to figure out the padding.  (I guess the compiler
could make an exception in the case of parameters passed on the
stack.)  It just seems like frequently code assumes that the
sizeof(variable) is exactly equal to the offset of that variable from
the next one.
-- 
Perry Smith
ctvax ---\
megamax --- bobkat!pedz
pollux---/

msb@dciem.UUCP (Mark Brader) (10/17/86)

Perry Smith (pedz@bobkat.UUCP) writes:
> In article <1971@dciem.UUCP> msb@dciem.UUCP (Mark Brader) says that in
> effect (&variable + sizeof(variable) > &nextvariable) is possible.

This should, of course, be ((char *) &variable + sizeof(variable) >
(char *) &nextvariable).  I'm not saying that Perry doesn't know this,
since he said "in effect", but just reminding anyone who might be fooled.

> While I understand his argument and reasoning, I hope that this is not
> true.

Agreed.  And no one has yet come forth to say that it is true on their
machine, so maybe it is in fact never true.

Mark Brader