struct alignment

Discussion in 'C Programming' started by Mark, Jan 11, 2012.

  1. Mark

    Mark Guest

    Hello:

    #define MAX_SIZE 8

    enum my_enum
    {
    VAL1 = 0;
    VAL2,
    VAL3,
    VAL4,
    VAL_MAX
    };

    struct my_struct
    {
    enum my_enum e;
    int w[MAX_SIZE];
    };

    Can a layout in such structure cause alignment issues on a target platform?
    I understand it much depends on a platform, but generally C compiler is
    allowed to do padding of structures, so for example on 32 bit machine, where
    'int' is 32 bit long:

    struct my_struct
    {
    int w[MAX_SIZE];
    }

    is aligned (as fas as I understand) so compiler probably won't be doing
    anything else with its layout, but adding 'enum my_enum' in the structure
    can poptentially get the structure un-aligned on such machine. Should I be
    doing anything special to avoid this and should I be avoiding it at all ?

    Would be very thankful for clarifications!

    Mark
     
    Mark, Jan 11, 2012
    #1
    1. Advertising

  2. Mark

    Kleuske Guest

    On Wed, 11 Jan 2012 13:31:53 -0500, Mark saw fit to publish the following:

    > Hello:
    >
    > #define MAX_SIZE 8
    >
    > enum my_enum
    > {
    > VAL1 = 0;
    > VAL2,
    > VAL3,
    > VAL4,
    > VAL_MAX
    > };
    >
    > struct my_struct
    > {
    > enum my_enum e;
    > int w[MAX_SIZE];
    > };
    >
    > Can a layout in such structure cause alignment issues on a target
    > platform? I understand it much depends on a platform, but generally C
    > compiler is allowed to do padding of structures, so for example on 32
    > bit machine, where 'int' is 32 bit long:
    >
    > struct my_struct
    > {
    > int w[MAX_SIZE];
    > }
    >
    > is aligned (as fas as I understand) so compiler probably won't be doing
    > anything else with its layout, but adding 'enum my_enum' in the
    > structure can poptentially get the structure un-aligned on such machine.
    > Should I be doing anything special to avoid this and should I be
    > avoiding it at all ?
    >
    > Would be very thankful for clarifications!
    >
    > Mark


    In general you should not rely on things being padded or not. Not only can
    it differ on different machines, it can differ for different settings of the
    same compiler.

    Behind the scenes, an enum is treated like an integer and the same issues can
    arise. If your code depends on things being padded this or that way or not at
    all, start thinking about ways of doing it differently.

    --
    Schshschshchsch.
    -- The Gorn, "Arena", stardate 3046.2
     
    Kleuske, Jan 11, 2012
    #2
    1. Advertising

  3. "Mark" <> wrote:

    > Can a layout in such structure cause alignment issues on a target
    > platform? I understand it much depends on a platform, but generally
    > C compiler is allowed to do padding of structures, so for example
    > on 32 bit machine, where 'int' is 32 bit long:
    >
    > struct my_struct
    > {
    > int w[MAX_SIZE];
    > }
    >
    > is aligned (as fas as I understand) so compiler probably won't
    > be doing anything else with its layout, but adding 'enum
    > my_enum' in the structure can poptentially get the structure
    > un-aligned on such machine. Should I be doing anything special
    > to avoid this and should I be avoiding it at all ?


    No, you don't need to care. Each structure member will be aligned
    according to its own requirements and the whole structure will meet
    these requirements, too (as long as esp. for malloc()ed memory the
    returned pointer has not been changed "unalignedly" later by the
    program).

    -- Ralf
     
    Ralf Damaschke, Jan 11, 2012
    #3
  4. "Mark" <> writes:
    > #define MAX_SIZE 8
    >
    > enum my_enum
    > {
    > VAL1 = 0;
    > VAL2,
    > VAL3,
    > VAL4,
    > VAL_MAX
    > };
    >
    > struct my_struct
    > {
    > enum my_enum e;
    > int w[MAX_SIZE];
    > };
    >
    > Can a layout in such structure cause alignment issues on a target platform?
    > I understand it much depends on a platform, but generally C compiler is
    > allowed to do padding of structures, so for example on 32 bit machine, where
    > 'int' is 32 bit long:
    >
    > struct my_struct
    > {
    > int w[MAX_SIZE];
    > }
    >
    > is aligned (as fas as I understand) so compiler probably won't be doing
    > anything else with its layout, but adding 'enum my_enum' in the structure
    > can poptentially get the structure un-aligned on such machine. Should I be
    > doing anything special to avoid this and should I be avoiding it at all ?


    The compiler will (in fact, it *must*) insert whatever padding is
    necessary so that all the members can be accesssed correctly. It may or
    may not insert more padding than it strictly needs to.

    The language standard guarantees that the first declared member is at
    offset 0, and that all other members are at increasing offsets in the
    order in which they're declared (the compiler can't rearrange members).
    There can be arbitrary padding between members, or after the last one.

    Some compilers have extensions that allow you to request tighter packing
    (less padding) than the default. In at least one case, such an
    extension can cause serious problems on some platforms; see:
    http://stackoverflow.com/questions/8568432/
    http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51628

    But if just let the compiler do its job and write portable code (and
    don't make assumptions about padding), there shouldn't be any problems.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 11, 2012
    #4
  5. Mark

    Dr Nick Guest

    Keith Thompson <> writes:

    > The compiler will (in fact, it *must*) insert whatever padding is
    > necessary so that all the members can be accesssed correctly. It may or
    > may not insert more padding than it strictly needs to.
    >
    > The language standard guarantees that the first declared member is at
    > offset 0, and that all other members are at increasing offsets in the
    > order in which they're declared (the compiler can't rearrange
    > members).


    Does any compiler let you do this? I have done things where the order
    of a least some elements (usually the first or the last) matters, but
    it's rare.

    > There can be arbitrary padding between members, or after the last one.
    >
    > Some compilers have extensions that allow you to request tighter packing
    > (less padding) than the default.


    I can think of cases where re-arranging could give significant space
    savings without these risks.

    In response to the obvious "why don't you do it?" there are a couple of
    reasons. One, of course, that it will vary from platform to platform.
    The second is that quite often there is a logical order or partial order
    of fields from a program logic point of view that is different to the
    most efficient.

    For example, you might want to start off with a small integer to say
    what type of object you have, have a few pointers that point to various
    type-specific things, then an integer reference count and then a pointer
    to the next one in a list.

    Shoving the two integers together could well save you some memory with
    out the need for the compiler to generate fancy code (as in the "packed"
    case) but at the loss of program source clarity.
    --
    Online waterways route planner | http://canalplan.eu
    Plan trips, see photos, check facilities | http://canalplan.org.uk
     
    Dr Nick, Jan 12, 2012
    #5
  6. Mark

    Ian Collins Guest

    On 01/12/12 07:56 PM, Dr Nick wrote:
    > Keith Thompson<> writes:
    >
    >> The compiler will (in fact, it *must*) insert whatever padding is
    >> necessary so that all the members can be accesssed correctly. It may or
    >> may not insert more padding than it strictly needs to.
    >>
    >> The language standard guarantees that the first declared member is at
    >> offset 0, and that all other members are at increasing offsets in the
    >> order in which they're declared (the compiler can't rearrange
    >> members).

    >
    > Does any compiler let you do this? I have done things where the order
    > of a least some elements (usually the first or the last) matters, but
    > it's rare.


    Let you do what? I didn't see anything optional in Keith's reply.

    --
    Ian Collins
     
    Ian Collins, Jan 12, 2012
    #6
  7. Ian Collins <> writes:
    > On 01/12/12 07:56 PM, Dr Nick wrote:
    >> Keith Thompson<> writes:
    >>
    >>> The compiler will (in fact, it *must*) insert whatever padding is
    >>> necessary so that all the members can be accesssed correctly. It may or
    >>> may not insert more padding than it strictly needs to.
    >>>
    >>> The language standard guarantees that the first declared member is at
    >>> offset 0, and that all other members are at increasing offsets in the
    >>> order in which they're declared (the compiler can't rearrange
    >>> members).

    >>
    >> Does any compiler let you do this? I have done things where the order
    >> of a least some elements (usually the first or the last) matters, but
    >> it's rare.

    >
    > Let you do what? I didn't see anything optional in Keith's reply.


    Permit reordering of struct members, I presume. Plenty of C
    compilers have plenty of options that break standard compliance.

    For that matter, let me back off slightly from my statement above. A
    conforming C compiler could provide an implementation-defined #pragma
    directive that permits arbitrary reordering of struct members (for size
    minimization, for example). C99 6.10.6p1 says that a #pragma directive:

    causes the implementation to behave in an implementation-defined
    manner. The behavior might cause translation to fail or
    cause the translator or the resulting program to behave in a
    non-conforming manner.

    So a hypothetic implementation might have:

    struct reordered {
    #pragma REORDER_STRUCT_MEMBERS
    char c0;
    char c1;
    int i;
    };

    that could put i at offset 0, followed by c0 and c1.

    But I've never heard of a C compiler that actually does this.

    <OT>I've worked on an Ada compiler that did the equivalent of reordering
    struct members, but the Ada standard doesn't require members to be
    allocated in declared order.<?OT>

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 12, 2012
    #7
  8. Mark

    Jorgen Grahn Guest

    On Thu, 2012-01-12, Keith Thompson wrote:
    > Ian Collins <> writes:
    >> On 01/12/12 07:56 PM, Dr Nick wrote:
    >>> Keith Thompson<> writes:
    >>>
    >>>> The compiler will (in fact, it *must*) insert whatever padding is
    >>>> necessary so that all the members can be accesssed correctly. It may or
    >>>> may not insert more padding than it strictly needs to.
    >>>>
    >>>> The language standard guarantees that the first declared member is at
    >>>> offset 0, and that all other members are at increasing offsets in the
    >>>> order in which they're declared (the compiler can't rearrange
    >>>> members).
    >>>
    >>> Does any compiler let you do this? I have done things where the order
    >>> of a least some elements (usually the first or the last) matters, but
    >>> it's rare.

    >>
    >> Let you do what? I didn't see anything optional in Keith's reply.

    >
    > Permit reordering of struct members, I presume. Plenty of C
    > compilers have plenty of options that break standard compliance.


    But is it really breaking compliance?

    struct Foo {
    int a;
    char b;
    int c;
    char d;
    };

    If the compiler lays these out as a-c-b-d, is that really something
    which is observable using correct C code?

    I seem to recall (but I can be wrong) that the expression
    &foo.b < &foo.d is not guaranteed to be meaningful, unlike e.g.
    comparisons inside an array.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Jan 18, 2012
    #8
  9. Mark

    Kaz Kylheku Guest

    On 2012-01-18, Jorgen Grahn <> wrote:
    > On Thu, 2012-01-12, Keith Thompson wrote:
    >> Ian Collins <> writes:
    >>> On 01/12/12 07:56 PM, Dr Nick wrote:
    >>>> Keith Thompson<> writes:
    >>>>
    >>>>> The compiler will (in fact, it *must*) insert whatever padding is
    >>>>> necessary so that all the members can be accesssed correctly. It may or
    >>>>> may not insert more padding than it strictly needs to.
    >>>>>
    >>>>> The language standard guarantees that the first declared member is at
    >>>>> offset 0, and that all other members are at increasing offsets in the
    >>>>> order in which they're declared (the compiler can't rearrange
    >>>>> members).
    >>>>
    >>>> Does any compiler let you do this? I have done things where the order
    >>>> of a least some elements (usually the first or the last) matters, but
    >>>> it's rare.
    >>>
    >>> Let you do what? I didn't see anything optional in Keith's reply.

    >>
    >> Permit reordering of struct members, I presume. Plenty of C
    >> compilers have plenty of options that break standard compliance.

    >
    > But is it really breaking compliance?
    >
    > struct Foo {
    > int a;
    > char b;
    > int c;
    > char d;
    > };
    >
    > If the compiler lays these out as a-c-b-d, is that really something
    > which is observable using correct C code?
    >
    > I seem to recall (but I can be wrong) that the expression
    > &foo.b < &foo.d is not guaranteed to be meaningful, unlike e.g.
    > comparisons inside an array.


    C has an offsetof macro, such that offsetof(struct Foo, a) == 0 has to hold,
    and the offsets of the other members have to be in increasing order.

    Reordering struct members would break all kinds of code, not all of which is
    ISO C mandated.

    For instance maintaining backward binary compatibility in shared library
    interfaces for structures that are allocated outside of the library
    (e.g. in static or automatic storage in client code).

    /* Maintainers! Add new members only at the end. */
    struct Foo {
    int a; /* Lib 1.0 members */
    char b;
    int c; /* Added in 1.2 */
    char d; /* New in 1.3 */
    };

    In this case, the above struct has to be compatible with the one
    compiled in the existing 1.0 clients which is just this:

    struct Foo {
    int a; /* Lib 1.0 members */
    char b;
    };

    (Knowledge about which type of client is attached to the library can be used to
    carefully avoid touching members c and d.)

    Sometimes structs are used to conform to an external storage layout,
    or hardware registers.
     
    Kaz Kylheku, Jan 18, 2012
    #9
  10. On 18-Jan-12 11:03, Jorgen Grahn wrote:
    > On Thu, 2012-01-12, Keith Thompson wrote:
    >> Ian Collins <> writes:
    >>> On 01/12/12 07:56 PM, Dr Nick wrote:
    >>>> Keith Thompson<> writes:
    >>>>> The compiler will (in fact, it *must*) insert whatever padding is
    >>>>> necessary so that all the members can be accesssed correctly. It may or
    >>>>> may not insert more padding than it strictly needs to.
    >>>>>
    >>>>> The language standard guarantees that the first declared member is at
    >>>>> offset 0, and that all other members are at increasing offsets in the
    >>>>> order in which they're declared (the compiler can't rearrange
    >>>>> members).
    >>>>
    >>>> Does any compiler let you do this? I have done things where the order
    >>>> of a least some elements (usually the first or the last) matters, but
    >>>> it's rare.
    >>>
    >>> Let you do what? I didn't see anything optional in Keith's reply.

    >>
    >> Permit reordering of struct members, I presume. Plenty of C
    >> compilers have plenty of options that break standard compliance.

    >
    > But is it really breaking compliance?
    >
    > struct Foo {
    > int a;
    > char b;
    > int c;
    > char d;
    > };
    >
    > If the compiler lays these out as a-c-b-d, is that really something
    > which is observable using correct C code?


    Yes, using offsetof(). And there are plenty of cases where this
    actually matters in real-world code.

    > I seem to recall (but I can be wrong) that the expression
    > &foo.b < &foo.d is not guaranteed to be meaningful, unlike e.g.
    > comparisons inside an array.


    It's guaranteed to be meaningful.

    N1256, 6.5.8.5:
    "If the objects pointed to are members of the same aggregate object,
    pointers to structure members declared later compare greater than
    pointers to members declared earlier in the structure, ..."

    Reordering structure members is therefore a constraint violation, and
    any compiler that does it is non-compliant.

    S

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking
     
    Stephen Sprunk, Jan 18, 2012
    #10
  11. Stephen Sprunk <> writes:
    [...]
    > Reordering structure members is therefore a constraint violation, and
    > any compiler that does it is non-compliant.


    A "constraint violation" is an error in code. Errors in compilers are
    just bugs.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 18, 2012
    #11
  12. Mark

    Jorgen Grahn Guest

    On Wed, 2012-01-18, Robert Wessel wrote:
    > On 18 Jan 2012 17:03:55 GMT, Jorgen Grahn <>
    > wrote:
    >
    >>On Thu, 2012-01-12, Keith Thompson wrote:
    >>> Ian Collins <> writes:
    >>>> On 01/12/12 07:56 PM, Dr Nick wrote:
    >>>>> Keith Thompson<> writes:
    >>>>>
    >>>>>> The compiler will (in fact, it *must*) insert whatever padding is
    >>>>>> necessary so that all the members can be accesssed correctly. It may or
    >>>>>> may not insert more padding than it strictly needs to.
    >>>>>>
    >>>>>> The language standard guarantees that the first declared member is at
    >>>>>> offset 0, and that all other members are at increasing offsets in the
    >>>>>> order in which they're declared (the compiler can't rearrange
    >>>>>> members).
    >>>>>
    >>>>> Does any compiler let you do this? I have done things where the order
    >>>>> of a least some elements (usually the first or the last) matters, but
    >>>>> it's rare.
    >>>>
    >>>> Let you do what? I didn't see anything optional in Keith's reply.
    >>>
    >>> Permit reordering of struct members, I presume. Plenty of C
    >>> compilers have plenty of options that break standard compliance.

    >>
    >>But is it really breaking compliance?
    >>
    >> struct Foo {
    >> int a;
    >> char b;
    >> int c;
    >> char d;
    >> };
    >>
    >>If the compiler lays these out as a-c-b-d, is that really something
    >>which is observable using correct C code?
    >>
    >>I seem to recall (but I can be wrong) that the expression
    >>&foo.b < &foo.d is not guaranteed to be meaningful, unlike e.g.
    >>comparisons inside an array.


    > It's also required that structures with common leading sections have
    > the same in-storage layout.


    Ok, that is enough reason for not allowing reordering. To me, the
    real reason then seems to be to allow things like the POSIX struct
    sockaddr/sockaddr_in/sockaddr_in6/... hack. I always assumed the
    sockaddr stuff demanded stronger guarantees from the compiler than the
    standard gives.

    > Of course that's all subject to the as-if rule, if the compiler can
    > determine that the program never looks at the ordering, or the
    > compiler can fake it, it's allowed to do anything it wants under the
    > covers, including omitting and reordering parts or all of the
    > structure.


    Yes, but that surely is rare. :-( Most structs are not limited to one
    translation unit.

    I agree with whoever-it-was upthread: if it was allowed to do it, the
    compiler could do a much better layout of my structs than I am willing
    to do manually.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Jan 19, 2012
    #12
  13. Mark

    Joe keane Guest

    In article <>,
    Kaz Kylheku <> wrote:
    >Reordering struct members would break all kinds of code, not all of which is
    >ISO C mandated.


    It would be a cool option though...

    struct apple
    {
    char x;
    double y;
    };

    struct vector
    {
    __rearrangeok
    struct apple e[5];
    };

    ->

    struct vectorn
    {
    char exz[5];
    double eyz[5];
    };
     
    Joe keane, Jan 19, 2012
    #13
  14. Mark

    Ben Pfaff Guest

    (Joe keane) writes:

    > In article <>,
    > Kaz Kylheku <> wrote:
    >>Reordering struct members would break all kinds of code, not all of which is
    >>ISO C mandated.

    >
    > It would be a cool option though...


    C++ has something a little like this. If you write "public:"
    between each pair of members, then the compiler is allowed to
    arrange them the members in any order, except that (based on a
    quick reading, anyway) the first member declared still has to be
    first.
    --
    "This is a wonderful answer.
    It's off-topic, it's incorrect, and it doesn't answer the question."
    --Richard Heathfield
     
    Ben Pfaff, Jan 19, 2012
    #14
  15. Mark

    Jorgen Grahn Guest

    On Thu, 2012-01-19, Robert Wessel wrote:
    > On 19 Jan 2012 11:34:43 GMT, Jorgen Grahn <>
    > wrote:
    >
    >>On Wed, 2012-01-18, Robert Wessel wrote:

    ....
    >>> Of course that's all subject to the as-if rule, if the compiler can
    >>> determine that the program never looks at the ordering, or the
    >>> compiler can fake it, it's allowed to do anything it wants under the
    >>> covers, including omitting and reordering parts or all of the
    >>> structure.

    >>
    >>Yes, but that surely is rare. :-( Most structs are not limited to one
    >>translation unit.
    >>
    >>I agree with whoever-it-was upthread: if it was allowed to do it, the
    >>compiler could do a much better layout of my structs than I am willing
    >>to do manually.


    > Perhaps not so rare - a common case occurs when a (small-ish)
    > structure is passed to or returned from a function that gets inlined.
    > In C++ you see that in a lot of implicitly generated temporaries. Two
    > cases in particular I've seen are in some graphics code where a
    > "point" or "pixel" structure was so treated, and in code with a
    > "complex" structure for representing, *ahem*, complex numbers. Of
    > course none of those examples would typically involve any alignment
    > issues.


    True, and that is a case where I assume the compiler does something
    smart. I automatically assume that in C too, but perhaps that's due
    to my C++ training.

    [...]

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Jan 21, 2012
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bryan Parkoff
    Replies:
    0
    Views:
    439
    Bryan Parkoff
    Apr 2, 2005
  2. Eric G.

    Re: Struct Alignment

    Eric G., Aug 3, 2003, in forum: C Programming
    Replies:
    2
    Views:
    358
    Richard Heathfield
    Aug 4, 2003
  3. Jack Klein

    Re: Struct Alignment

    Jack Klein, Aug 4, 2003, in forum: C Programming
    Replies:
    0
    Views:
    412
    Jack Klein
    Aug 4, 2003
  4. Chris Fogelklou
    Replies:
    36
    Views:
    1,410
    Chris Fogelklou
    Apr 20, 2004
  5. S.Tobias

    struct and union alignment

    S.Tobias, Sep 23, 2004, in forum: C Programming
    Replies:
    67
    Views:
    1,380
    Dave Thompson
    Oct 4, 2004
Loading...

Share This Page