cvs commit: src/include ar.h

Bruce Evans bde at zeta.org.au
Sun Nov 19 10:11:55 UTC 2006


On Sat, 18 Nov 2006, Marcel Moolenaar wrote:

> On Nov 18, 2006, at 12:21 PM, Yar Tikhiy wrote:
>> 
>> The C standard provides no clues as to how structures are packed
>> or aligned.  The only thing it says is that objects have alignment
>> and it can be the same or not the same for different objects.  That

It has implicit requirements for alignment of structs.  Since there is
no padding before the first member, the alignment of a struct must be
at least that of its first member.  Since there is no padding between
elements of arrays, I don't know of any reasonable way to implement
an array of structs without aligning the struct to a multiple of the
size of all its members and padding it to this size.

>> is, a future C compiler is allowed to put holes in struct ip, and
>> in any struct it wants, unless we use the unportable __packed hack
>> -- or abandon the structs in favor of byte-level access to seamless
>> data such as hardware or network packets.  That's what I meant by
>> struct ip being historically lucky.

ABIs prevent the layout changing in future versions for the same arch.

> Also, since this discussion is the result of ARM aligning structures
> on 4-byte boundaries, I think that the use of __packed to compensate
> for excessive alignment is just plain wrong. We have __aligned(x) to
> inform the compiler about what the alignment of an object should be
> and that's the tool we should use to tell the compiler on ARM that
> we in fact want 1-byte alignment. take for example, the following
> structure:
>
> struct {
> 	uint8_t	 a;
> 	uint16_t b;
> };

Unfortunately, declaring this as just __aligned(1) doesn't work on ia64, so
I doubt that it works on arm.  (On ia64, it doesn't affect the padding
in the middle.)  I think it would only work for structs that are naturally
packed without use of __packed, but if you're going to be unportable and
used __aligned() then you may as well used __packed too.  I think
__aligned() is only mainly needed to recover from using __packed.
Everthing is aligned unless you break the alignment using __packed or
a bogus cast.

gcc.info says that SysV's #pragma packed(<n>) is equivalent to __packed
plus __aligned(<n>).  I'm not sure if (<n>) is optional.  This has the
advantages of making it harder to forget that packing implies (mis)alignment
and easier to pack to boundaries other than 1.

Compiling my normal kernel configuration with -Wpacked on amd64 fails to
produce only about 1/7 of the object files (due to just a few headers
with bogus __packed's being included by more than a few source files).
Compiling with -Wpadded succeeds in producing about 7 object files (due
to central headers having poorly manually packed structs).

Bruce


More information about the cvs-src mailing list