Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Padding at the end of structures

10 views
Skip to first unread message

Dag-Erling Smørgrav

unread,
Jul 9, 2009, 11:51:47 AM7/9/09
to
§6.7.2.1 allows, but does not require, padding at the end of a structure
or union.

Logically, such padding is required to ensure proper alignment of
elements in an array of structures. Take the following declaration:

struct foo { int i; char c; } bar[2];

Assuming a four-byte alignment requirement for int, and hence for struct
foo, the compiler should add three bytes of padding at the end of struct
foo so bar[1] is correctly aligned.

Can anyone help me find a reference (or set of references) to support
the notion that this is a requirement, and not just a good idea?

DES
--
Dag-Erling Smørgrav - d...@des.no

Francis Glassborow

unread,
Jul 9, 2009, 1:25:10 PM7/9/09
to

It falls out from the requirements for elements of an array to be
contiguous.

Given

atype array[100];

array + 1 must point to the second element of array. But it is also
required that:

char * ptr0 = ((char *) array )+ sizeof atype

char * ptr1 = (char*) (array +1);
if (ptr0 == ptr1) puts(" the same");
else puts("different");

output:
the same

Eric Sosman

unread,
Jul 9, 2009, 1:25:50 PM7/9/09
to

Probably not, because both the alignment requirements and the
penalties for disregarding them are implementation-specific. An
implementation *could* eliminate all padding, effectively making
the alignment requirement of every type the same as that of `char',
by some such dodge as using char-at-a-time accesses to fetch and
store unaligned data. (Consider, for example, the consequences of
using an extension like `#pragma pack' or `__attribute__((packed))'
to squeeze the padding bytes out of a struct.)

At the C source level, though, the implementation must make
sure that the accesses work properly. `bar[1].i = 42' must behave
as expected, regardless of whether the implementation uses padding
to make it work or uses trickery of some other kind.

--
Eric....@sun.com

Dag-Erling Smørgrav

unread,
Jul 10, 2009, 6:28:42 AM7/10/09
to
Eric Sosman <Eric....@sun.com> writes:
> Probably not, because both the alignment requirements and the
> penalties for disregarding them are implementation-specific. An
> implementation *could* eliminate all padding, effectively making
> the alignment requirement of every type the same as that of `char',
> by some such dodge as using char-at-a-time accesses to fetch and
> store unaligned data.

You missed the part where I wrote "assuming a four-byte alignment
requirement for int".

Eric Sosman

unread,
Jul 10, 2009, 8:35:34 AM7/10/09
to

No, I didn't miss it; I ignored it as irrelevant. Your
question was whether the padding was "a requirement," and
assumptions about a particular platform's characteristics
don't extend as requirements for all other platforms.

Even granting the assumption, padding could be eliminated
at some cost in speed using char-at-a-time techniques. (The
interaction with `volatile' might be unpleasant, but there's
enough fuzziness around `volatile' that we can ignore it.)

Finally, even on a particular platform the "requirement"
to align a data type can be fuzzy. For example, there is a
widely-used family of machines that can access a `double' on
any four-byte boundary, but can access it faster if it is
aligned to eight bytes. What is the alignment "requirement"
for `double' on such a machine? Answer: The implementor
chooses and having chosen moves on, nor all thy piety nor
wit can call him back to cancel half an align ...

--
Eric Sosman
eso...@ieee-dot-org.invalid

James Kuyper

unread,
Jul 10, 2009, 10:08:20 AM7/10/09
to
Eric Sosman wrote:

> Dag-Erling Smørgrav wrote:
>> Eric Sosman <Eric....@sun.com> writes:
>>> Probably not, because both the alignment requirements and the
>>> penalties for disregarding them are implementation-specific. An
>>> implementation *could* eliminate all padding, effectively making
>>> the alignment requirement of every type the same as that of `char',
>>> by some such dodge as using char-at-a-time accesses to fetch and
>>> store unaligned data.
>>
>> You missed the part where I wrote "assuming a four-byte alignment
>> requirement for int".
>
> No, I didn't miss it; I ignored it as irrelevant. Your
> question was whether the padding was "a requirement," and
> assumptions about a particular platform's characteristics
> don't extend as requirements for all other platforms.

That's true, but doesn't render his assumption irrelevant. He was asking
a question about what alignment requirements mean, and by stating his
assumption, explicitly restricting the scope of his question to those
implementations where there are meaningful alignment restrictions,
correctly described by "four-byte alignment". Your answer was more
appropriate for a different, more general question - a question that he
did not in fact ask, and whose answer has little to do with the correct
answer to the more specific question that he did actually ask.

> Even granting the assumption, padding could be eliminated
> at some cost in speed using char-at-a-time techniques.

If the padding can be eliminated, then the alignment is not actually a
requirement, and you're therefore talking about an implementation not
meeting the assumption that defines the context of the question.

> Finally, even on a particular platform the "requirement"
> to align a data type can be fuzzy. For example, there is a
> widely-used family of machines that can access a `double' on
> any four-byte boundary, but can access it faster if it is
> aligned to eight bytes. What is the alignment "requirement"
> for `double' on such a machine? Answer: The implementor
> chooses and having chosen moves on, nor all thy piety nor
> wit can call him back to cancel half an align ...

Sure, it's an implementation choice. The point is, having made that
choice, what are the implications of the choice that was made? In
particular, getting back to the original question:

Dag-Erling Smørgrav wrote:
...


> struct foo { int i; char c; } bar[2];
>
> Assuming a four-byte alignment requirement for int, and hence for struct
> foo, the compiler should add three bytes of padding at the end of struct
> foo so bar[1] is correctly aligned.


The implementation's choice to set the alignment requirement for 'int'
to 4 does in fact imply that padding must be added; however, the padding
could be added either before or after the member named 'c'.

Wojtek Lerch

unread,
Jul 10, 2009, 10:28:08 AM7/10/09
to
"Eric Sosman" <eso...@ieee-dot-org.invalid> wrote in message
news:h37cio$ml1$1...@news.eternal-september.org...

> Dag-Erling Smørgrav wrote:
>> You missed the part where I wrote "assuming a four-byte alignment
>> requirement for int".
>
> Even granting the assumption, padding could be eliminated
> at some cost in speed using char-at-a-time techniques.

That depends on whether the assumption talks about some sort of hardware
alignment requirements or the alignment requirements that the C standard
talks about.

A C implementation can eliminate padding by relaxing its alignment
requirements. This could involve working around hardware alignent
requirements using char-at-a-time techniques.

But on any implementation where the alignment requirement, in the C sense,
is four bytes for int, then any structure that contains an int must be
padded to a multiple of four bytes.

Eric Sosman

unread,
Jul 10, 2009, 12:04:32 PM7/10/09
to
James Kuyper wrote:
> Eric Sosman wrote:
>> Dag-Erling Smørgrav wrote:
>>> Eric Sosman <Eric....@sun.com> writes:
>>>> Probably not, because both the alignment requirements and the
>>>> penalties for disregarding them are implementation-specific. An
>>>> implementation *could* eliminate all padding, effectively making
>>>> the alignment requirement of every type the same as that of `char',
>>>> by some such dodge as using char-at-a-time accesses to fetch and
>>>> store unaligned data.
>>>
>>> You missed the part where I wrote "assuming a four-byte alignment
>>> requirement for int".
>>
>> No, I didn't miss it; I ignored it as irrelevant. Your
>> question was whether the padding was "a requirement," and
>> assumptions about a particular platform's characteristics
>> don't extend as requirements for all other platforms.
>
> That's true, but doesn't render his assumption irrelevant. He was asking
> a question about what alignment requirements mean, and by stating his
> assumption, explicitly restricting the scope of his question to those
> implementations where there are meaningful alignment restrictions,
> correctly described by "four-byte alignment".

His actual question was "Can anyone help me find a reference
(or set of references) to support the notion that this [padding
for alignment] is a requirement, and not just a good idea?" He
did not ask "What do alignment requirements mean?" and I think
we can take it as read that he understands what they mean and
what they are.

The point I'm trying to make is that alignment "requirements"
are creatures of the implementation, not of a reference governing
all implementations. The C Standard acknowledges the possible
existence of alignment requirements, and goes on to describe them
in terms of a divisibility condition on addresses-as-numbers, but
does not attempt to explain the possible causes or motivations of
such requirements. Also, I've tried to show that "requirement"
is itself not all that rigidly defined.

A particular implementation will have its own rules about
alignment, and will enforce those rules with whatever rigor the
implementor decides on. There's not going to be an external
standard somewhere that requires a particular set of rules nor
a given level of enforcement.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Richard Bos

unread,
Jul 10, 2009, 5:32:19 PM7/10/09
to
=?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <d...@des.no> wrote:

No; since all objects can be accessed as arrays of unsigned char, all
such requirements can be worked around by a sufficiently perverse
implementation.

However, even if the implementation honours the alignment of int, there
need not be three bytes of padding after the char member. There may also
be three bytes between the int and the char, or even one between and two
after, or /vice versa/. In fact, depending on endianness and the speed
of multi-byte access assembler instructions, any of those might be more
efficient than having the padding after. I don't expect to find them in
the wild any time soon, but OTOH, neither would I be surprised to.

Richard

James Kuyper

unread,
Jul 10, 2009, 8:51:59 PM7/10/09
to
Richard Bos wrote:
> =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= <d...@des.no> wrote:
>
>> Eric Sosman <Eric....@sun.com> writes:
>>> Probably not, because both the alignment requirements and the
>>> penalties for disregarding them are implementation-specific. An
>>> implementation *could* eliminate all padding, effectively making
>>> the alignment requirement of every type the same as that of `char',
>>> by some such dodge as using char-at-a-time accesses to fetch and
>>> store unaligned data.
>> You missed the part where I wrote "assuming a four-byte alignment
>> requirement for int".
>
> No; since all objects can be accessed as arrays of unsigned char, all
> such requirements can be worked around by a sufficiently perverse
> implementation.

An implementation that works around those difficulties does not have an
alignment requirement, the fact that it works around them means that
alignment is not actually required.

Richard Bos

unread,
Jul 12, 2009, 7:26:10 AM7/12/09
to
James Kuyper <james...@verizon.net> wrote:

In that case, alignment limits do not exist anywhere, since fiddling
around with arrays of unsigned char is always allowed. Usually
idiotically inefficient, but allowed.

Richard

James Kuyper

unread,
Jul 12, 2009, 9:21:51 AM7/12/09
to
Richard Bos wrote:
> James Kuyper <james...@verizon.net> wrote:
>
>> Richard Bos wrote:
...

>>> No; since all objects can be accessed as arrays of unsigned char, all
>>> such requirements can be worked around by a sufficiently perverse
>>> implementation.
>> An implementation that works around those difficulties does not have an
>> alignment requirement, the fact that it works around them means that
>> alignment is not actually required.
>
> In that case, alignment limits do not exist anywhere, since fiddling
> around with arrays of unsigned char is always allowed. Usually
> idiotically inefficient, but allowed.

An implementation that chooses not to fiddle in that fashion does, by
that choice, impose alignment requirements.

0 new messages