structure alignment question

John Mashey mash at mips.UUCP
Fri Sep 19 18:54:00 AEST 1986

In article <7363 at sun.uucp> guy at sun.uucp (Guy Harris) writes:
>> reply to:
>> Question:  Should structures and unions always be aligned to 4-byte
>>            boundaries? <....example follows:...>
>Yes, at least in the 4.3BSD version of the compiler, ....
Actually, some might be aligned to 8-byte boundaries, on machines that
like doubles on such boundaries.

>K&R does not seem to say anything about the addressing boundaries
>appropriate to structures or unions in the Reference Manual, but it implies
>that the addressing boundary appropriate to a union, at least, is that of
>the member with the most restrictive addressing boundary on page 174 of
>chapter 8, where it suggests that in order to align a given structure on a
>boundary more restrictive than its "natural" boundary, you place it in a
>union with an object with the desired alignment boundary.
>The ANSI C draft seems to say much the same thing, and gives little
>additional detail.  (If it's stored somewhere not indexed under "alignment",
>let me know; I only looked in the Index under "alignment".)
Guy is correct, as usual.  The key info is (trickily) found under sizeof:
ANSI C, section C.3.3.4 The sizeof operator, says:
"... When applied to an operand that has structure or union type, the result is
the total nubmer of bytes in such a member considered as a member of an array,
including whatever internal and trailing paddiing might be needed to align each
member in such an array properly.... Another use of the sizeof operator is to
compute the number of members in an array:  sizeof array / sizeof array[0];

Note that the net combination requires that:
	a) Any union or structure must be aligned on the most restrictive
	boundary of any of its members, including member structures.
	b) It's size must be rounded up to a multiple of that same size.
Anything else causes the above usage of sizeof to be unrobust in the face of:
	struct { ..... } array[number];

Note that for speed, it is usually best to align data items on the most
restrictive boundaries, even if a specific machine implementation doesn't
really require it.  Lots of machines let words be on arbitrary boundaries,
but you pay for it in speed, if not now, then later, as CPUs come
to have wider data paths.  A perfect case is the surprise going from
680[01]s to 68020s: if you let long's be aligned on 2-byte, but not necesarily
4-byte boundaries, and if you want to convert to 68020s without converting
data saved in such format, you lose performance you might have had.
(Of course, some space is saved; in practice, it's seldom large.)

Question for the audience: what implementations thought ahead about potential
64-bit buses and aligned doubles on 8-byte boundaries? try this:
main(argc, argv) {
	struct x {
		long i;
		double j;
	} y;
	printf("%x,%x, %d\n", &y.i, &y.j, sizeof y);
-john mashey	DISCLAIMER: <generic disclaimer, I speak for me only, etc>
UUCP: 	{decvax,ucbvax,ihnp4}!decwrl!mips!mash, DDD:  	408-720-1700, x253
USPS: 	MIPS Computer Systems, 930 E. Arques, Sunnyvale, CA 94086

More information about the Comp.lang.c mailing list