Structure padding.

Discussion in 'C Programming' started by Amarendra, Jun 21, 2004.

  1. Amarendra

    Amarendra Guest

    Folks,

    This structure padding issue is bothering me now, could
    not locate a satisfactory answer on clc, so here it goes...

    I have a structure, given below:
    typedef struct {
    int flag;
    char keys[3][9];
    char padding[??];
    } foo;

    I need to fill in the size of padding array here so as to
    make the entire structure size a multiple of 8. Is there
    a way in which I can calculate the padding ? This structure
    will be used on AIX 5.* and RHL.

    Thanks in advance.

    Cheers,
    Amar

    --
    If you don't want to succeed, nobody will try to stop you.
    Amarendra, Jun 21, 2004
    #1
    1. Advertising

  2. On Mon, 21 Jun 2004, Amarendra wrote:
    >
    > This structure padding issue is bothering me now, could
    > not locate a satisfactory answer on clc, so here it goes...
    >
    > I have a structure, given below:
    > typedef struct {
    > int flag;
    > char keys[3][9];
    > char padding[??];
    > } foo;
    >
    > I need to fill in the size of padding array here so as to
    > make the entire structure size a multiple of 8. Is there
    > a way in which I can calculate the padding ?


    Obviously not. Any compiler is perfectly capable of padding
    your structure to make it a multiple of 8 bytes, minus 1, and
    there's nothing you can do about it, from the Standard's point
    of view.
    In practice, you'll probably be able to get away with a
    system-specific solution such as

    #define PAD_EIGHT(siz) ((siz) - (siz)/8*8)
    struct half_foo {
    int flag;
    char keys[3][9];
    };
    typedef struct {
    int flag;
    char keys[3][9];
    char padding[PAD_EIGHT(sizeof (struct half_foo))];
    } foo;

    or (even less portably but much clearer to the next guy)

    typedef struct {
    int flag;
    char keys[3][9];
    char padding[1]; /* Pad to a multiple of 8 bytes */
    } foo;

    In practice, of course, it doesn't matter at all what the size
    of your structure is: let the computer worry about it. Most
    compilers have some kind of "optimize for speed/space" flag
    that will make your code run quickly no matter what the size of
    some little structure is.

    -Arthur
    Arthur J. O'Dwyer, Jun 21, 2004
    #2
    1. Advertising

  3. Amarendra

    -berlin.de Guest

    Amarendra <> wrote:
    > This structure padding issue is bothering me now, could
    > not locate a satisfactory answer on clc, so here it goes...


    > I have a structure, given below:
    > typedef struct {
    > int flag;
    > char keys[3][9];
    > char padding[??];
    > } foo;


    > I need to fill in the size of padding array here so as to
    > make the entire structure size a multiple of 8. Is there
    > a way in which I can calculate the padding ? This structure
    > will be used on AIX 5.* and RHL.


    That's something clc can't answer because there is no requirement
    on how much padding a compiler is supposed to use by the C standard.
    It obviously will differ between different architectures, but also
    compilers and maybe even different compiler versions. The first
    question that comes to mind is why you need the structures size to
    be a multiple of 8?

    <OT>
    You could write a script that writes C programs that create structures
    like the above with ever increasing lengths for the padding array and
    which then write out the sizeof the structure. The script compiles
    and runs these programs until the structures size is a multiple of 8
    and you use that length of the padding array in the real program (maybe
    by writing the value into an include file to be included by the real
    program). Shouldn't be too hard to do with a reasonably short script.
    </OT>
    Regards, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
    -berlin.de, Jun 21, 2004
    #3
  4. Amarendra

    Chris Torek Guest

    In article <>
    Amarendra <> writes:
    >This structure padding issue is bothering me now, could
    >not locate a satisfactory answer on clc, so here it goes...
    >
    >I have a structure, given below:
    > typedef struct {
    > int flag;
    > char keys[3][9];
    > char padding[??];
    > } foo;
    >
    >I need to fill in the size of padding array here so as to
    >make the entire structure size a multiple of 8. Is there
    >a way in which I can calculate the padding ? ...


    The answer is no -- and yes.

    There is no way to do it "in one pass", as it were, but you can
    still do it by generating the declaration at runtime, then (after
    this runtime has finished) use that declaration at a later
    compile-time.

    This does make some assumptions, such as "a later invocation of
    the compiler will use the same layout as an earlier invocation of
    the compiler" -- which should be true unless you wait too long (so
    that the compiler has been replaced with a later version), or change
    the set of flags you pass to the compiler. It also makes the build
    process for your software (much) more complicated: instead of just
    "compile all this C code", you have to do this, in sequence:

    - compile C code to generate the structure
    - run the program, putting the struct declaration into a file for
    use in the next step
    - compile the code that uses the newly-created declaration

    It is not clear to me why you want an explicit "padding blob". In
    my experience, most people who do that are trying to make the
    internal C structure layout meet some external file format -- which
    is often a mistake, as it is sometimes quite difficult to get an
    internal data structure to match external constraints at all, and
    often quite easy to make the input and output operations translate
    between "external" and "internal" formats. The translation code
    can either assume or force 8-bit "regular bytes" (octets) using "C
    bytes" (unsigned char), which are usually exactly 8 bits, and are
    never fewer than 8 bits. The "externalized" octets can be matched
    to the desired layout completely portably.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Jun 21, 2004
    #4
  5. Amarendra wrote:

    > Folks,
    >
    > This structure padding issue is bothering me now, could
    > not locate a satisfactory answer on clc, so here it goes...
    >
    > I have a structure, given below:
    > typedef struct {
    > int flag;
    > char keys[3][9];
    > char padding[??];
    > } foo;
    >
    > I need to fill in the size of padding array here so as to
    > make the entire structure size a multiple of 8. Is there
    > a way in which I can calculate the padding ? This structure
    > will be used on AIX 5.* and RHL.
    >
    > Thanks in advance.
    >
    > Cheers,
    > Amar
    >
    > --
    > If you don't want to succeed, nobody will try to stop you.


    In these cases, I revert to assembly language. Many assembly
    languages provide compiler directives to align data fields
    to a given boundary. I then "export" the symbol and use
    "extern" in the C language.

    --
    Thomas Matthews

    C++ newsgroup welcome message:
    http://www.slack.net/~shiva/welcome.txt
    C++ Faq: http://www.parashift.com/c -faq-lite
    C Faq: http://www.eskimo.com/~scs/c-faq/top.html
    alt.comp.lang.learn.c-c++ faq:
    http://www.raos.demon.uk/acllc-c /faq.html
    Other sites:
    http://www.josuttis.com -- C++ STL Library book
    Thomas Matthews, Jun 21, 2004
    #5
  6. On Mon, 21 Jun 2004 -berlin.de wrote:
    >
    > Amarendra <> wrote:
    > > I have a structure, given below:
    > > typedef struct {
    > > int flag;
    > > char keys[3][9];
    > > char padding[??];
    > > } foo;
    > >
    > > I need to fill in the size of padding array here so as to
    > > make the entire structure size a multiple of 8. Is there
    > > a way in which I can calculate the padding ? This structure
    > > will be used on AIX 5.* and RHL.


    > <OT>
    > You could write a script that writes C programs that create structures
    > like the above with ever increasing lengths for the padding array and
    > which then write out the sizeof the structure. The script compiles
    > and runs these programs until the structures size is a multiple of 8
    > and you use that length of the padding array in the real program (maybe
    > by writing the value into an include file to be included by the real
    > program). Shouldn't be too hard to do with a reasonably short script.
    > </OT>


    Hey, good idea! :)

    #include <stdio.h>

    #define PADSIZE(n) (sizeof(struct {int flag; char keys[9][3]; \
    char pad[n];}))
    #define PADOK(n) (PADSIZE(n)%8==0)
    #define PAD (PADOK(1)? 1: PADOK(2)? 2: PADOK(3)? 3: PADOK(4)? 4: \
    PADOK(5)? 5: PADOK(6)? 6: PADOK(7)? 7: PADOK(8)? 8: -1)

    typedef struct {
    int flag;
    char keys[9][3];
    char padding[PAD];
    } foo;

    (Naturally, the OP should not use this method. Nor should anyone else.)

    -Arthur
    Arthur J. O'Dwyer, Jun 21, 2004
    #6
  7. Amarendra

    Eric Sosman Guest

    Amarendra wrote:
    > Folks,
    >
    > This structure padding issue is bothering me now, could
    > not locate a satisfactory answer on clc, so here it goes...
    >
    > I have a structure, given below:
    > typedef struct {
    > int flag;
    > char keys[3][9];
    > char padding[??];
    > } foo;
    >
    > I need to fill in the size of padding array here so as to
    > make the entire structure size a multiple of 8. Is there
    > a way in which I can calculate the padding ? This structure
    > will be used on AIX 5.* and RHL.


    Others have pointed out that there's no completely
    guaranteed solution (because the compiler may add more
    padding bytes you have no control over). Others have
    also offered some non-guaranteed solutions involving
    macros and/or two passes. Here's a variation that
    might be simpler, if you can tolerate having the padding
    appear "after" the struct rather than inside it:

    typedef union { /* not struct */
    struct foo_data {
    int flag;
    char keys[3][9];
    } payload;
    char overlay[(sizeof(struct foo_data) + 7) / 8];
    } foo;

    A disadvantage is that you need to write things like
    `fooptr->payload.flag' instead of `fooptr->flag'. And,
    of course, the compiler might still decide to make the
    union larger than you want, and this might destroy the
    multiple-of-eight size.

    --
    Eric Sosman, Jun 21, 2004
    #7
  8. Amarendra

    Dan Pop Guest

    In <> (Amarendra) writes:

    >This structure padding issue is bothering me now, could
    >not locate a satisfactory answer on clc, so here it goes...
    >
    >I have a structure, given below:
    > typedef struct {
    > int flag;
    > char keys[3][9];
    > char padding[??];
    > } foo;
    >
    >I need to fill in the size of padding array here so as to
    >make the entire structure size a multiple of 8. Is there
    >a way in which I can calculate the padding ? This structure
    >will be used on AIX 5.* and RHL.


    Yes. It's not strictly guaranteed to work (it will fail if the struct
    needs to be aligned to multiples of something greater than 8 or that is
    not a power of two) and, in theory, the compiler may add some padding of
    its own at the end, but in practice you can calculate the padding if the
    compiler is happy with the idea of the structure size being a multiple of
    8. In the worst case you may have to add 8 bytes of padding, because
    you can't have arrays of size 0. Needless to say, the padding may
    differ between implementations (but this is transparent to the source
    code).

    There is more than way of doing it, but I prefer the one that completely
    virtualises the struct definition, at the expense of declaring an
    auxiliary structure, mirroring the real one, first:

    fangorn:~/tmp 155> cat test.c
    #include <stdio.h>
    #include <assert.h>
    #include <stddef.h>

    #define ALIGN 8

    struct foo_aux {
    int flag;
    char keys[3][9];
    char padding;
    };

    struct foo {
    int flag;
    char keys[3][9];
    char padding[ALIGN - offsetof(struct foo_aux, padding) % ALIGN];
    };

    int main()
    {
    assert(offsetof(struct foo_aux, padding) == offsetof(struct foo, padding));
    assert(sizeof(struct foo) % ALIGN == 0);
    printf("%d\n", (int)sizeof(struct foo));
    return 0;
    }
    fangorn:~/tmp 156> gcc test.c
    fangorn:~/tmp 157> ./a.out
    32

    The catch is that both struct definitions must be kept in sync, when
    changes are made. This is actually tested by the first assert. If the
    second assert fails, there is nothing you can do: the compiler is not
    happy with a structure size that is a multiple of 8.

    There is a way to automatically keep the two structures in sync, but I'm
    not very fond of it: put the common part of the two declarations in a
    separate file and include it. Change that file when you need to modify
    the structure definition. It's a readability vs maintenability tradeoff.

    fangorn:~/tmp 166> cat struct_foo.c
    int flag;
    char keys[3][9];
    fangorn:~/tmp 167> cat test.c
    #include <stdio.h>
    #include <assert.h>
    #include <stddef.h>

    #define ALIGN 8

    struct foo_aux {
    #include "struct_foo.c"
    char padding;
    };

    struct foo {
    #include "struct_foo.c"
    char padding[ALIGN - offsetof(struct foo_aux, padding) % ALIGN];
    };

    int main()
    {
    assert(sizeof(struct foo) % ALIGN == 0);
    printf("%d\n", (int)sizeof(struct foo));
    return 0;
    }
    fangorn:~/tmp 168> gcc test.c
    fangorn:~/tmp 169> ./a.out
    32

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Jun 21, 2004
    #8
  9. Amarendra

    Dan Pop Guest

    In <> Eric Sosman <> writes:

    >Amarendra wrote:
    >> This structure padding issue is bothering me now, could
    >> not locate a satisfactory answer on clc, so here it goes...
    >>
    >> I have a structure, given below:
    >> typedef struct {
    >> int flag;
    >> char keys[3][9];
    >> char padding[??];
    >> } foo;
    >>
    >> I need to fill in the size of padding array here so as to
    >> make the entire structure size a multiple of 8. Is there
    >> a way in which I can calculate the padding ? This structure
    >> will be used on AIX 5.* and RHL.

    >
    > Others have pointed out that there's no completely
    >guaranteed solution (because the compiler may add more
    >padding bytes you have no control over). Others have
    >also offered some non-guaranteed solutions involving
    >macros and/or two passes. Here's a variation that
    >might be simpler, if you can tolerate having the padding
    >appear "after" the struct rather than inside it:
    >
    > typedef union { /* not struct */
    > struct foo_data {
    > int flag;
    > char keys[3][9];
    > } payload;
    > char overlay[(sizeof(struct foo_data) + 7) / 8];
    > } foo;
    >
    >A disadvantage is that you need to write things like
    >`fooptr->payload.flag' instead of `fooptr->flag'.


    Another "disadvantage" is that you're grossly miscalculating the size of
    overlay, which is 8 times smaller than it should be! No point in
    dividing by 8 if you don't multiply back by 8 ;-)

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Jun 21, 2004
    #9
  10. Amarendra

    John Ilves Guest

    This seems to work for me (with gcc on linux):

    #include <stdio.h>

    struct foo
    {
    int flag : 4; /* force 32 bit */
    char keys[3][9]; /* 3 * 9 == 27 */
    int _pad_ : 1; /* 4 + 27 + 1 == 32, 32 % 8 == 0 */
    };

    int
    main()
    {
    printf( "struct foo is %d bytes, and %s divisible by 8\n",
    sizeof(struct foo),
    sizeof(struct foo) % 8 ? "is not" : "is" );

    return 0;
    }

    Hope it helps,
    John

    PS Nice email address. :)


    Amarendra wrote:
    > Folks,
    >
    > This structure padding issue is bothering me now, could
    > not locate a satisfactory answer on clc, so here it goes...
    >
    > I have a structure, given below:
    > typedef struct {
    > int flag;
    > char keys[3][9];
    > char padding[??];
    > } foo;
    >
    > I need to fill in the size of padding array here so as to
    > make the entire structure size a multiple of 8. Is there
    > a way in which I can calculate the padding ? This structure
    > will be used on AIX 5.* and RHL.
    >
    > Thanks in advance.
    >
    > Cheers,
    > Amar
    >
    > --
    > If you don't want to succeed, nobody will try to stop you.
    John Ilves, Jun 21, 2004
    #10
  11. On Mon, 21 Jun 2004, John Ilves wrote:
    >
    > This seems to work for me (with gcc on linux):

    [...]
    > struct foo
    > {
    > int flag : 4; /* force 32 bit */


    s/32/4/ . (You wrote "4" in the code and "32" in the comment.)

    > char keys[3][9]; /* 3 * 9 == 27 */
    > int _pad_ : 1; /* 4 + 27 + 1 == 32, 32 % 8 == 0 */


    But where's the missing dollar?

    Of course, no matter how many bits you use in your struct, GCC will
    generally pad it out to a decent multiple of 4 or 8 in any event.

    Because it's annoying as hell.
    Why not?
    And don't top-post.

    -Arthur
    Arthur J. O'Dwyer, Jun 21, 2004
    #11
  12. Amarendra

    Eric Sosman Guest

    John Ilves wrote:
    > This seems to work for me (with gcc on linux):
    >
    > #include <stdio.h>
    >
    > struct foo
    > {
    > int flag : 4; /* force 32 bit */


    ITYM "force 4 bit." Don't feel bad, though: everybody's
    entitled to one silly mistake per thread (and I've already
    claimed mine ...)

    > char keys[3][9]; /* 3 * 9 == 27 */
    > int _pad_ : 1; /* 4 + 27 + 1 == 32, 32 % 8 == 0 */


    `_pad_' happens to be safe in this context, but would
    be unsafe in most others. Stan Brown's list of identifiers
    to avoid

    http://www.oakroadsystems.com/tech/c-predef.htm

    is still based on the older C89 Standard and has not been
    updated for C99, but is still helpful.

    Oh, and the `: 1' doesn't do what you seem to believe.

    --
    Eric Sosman, Jun 21, 2004
    #12
  13. Amarendra

    John Ilves Guest

    Eric Sosman wrote:
    > John Ilves wrote:
    >
    >> This seems to work for me (with gcc on linux):
    >>
    >> #include <stdio.h>
    >>
    >> struct foo
    >> {
    >> int flag : 4; /* force 32 bit */

    >
    >
    > ITYM "force 4 bit." Don't feel bad, though: everybody's
    > entitled to one silly mistake per thread (and I've already
    > claimed mine ...)

    Heh, oops. Specifying struct field lengths isn't something I've used
    before, I've just heard about it. Obviously the 4 here should be a 32
    and the 1 for _pad_ should be an 8 since field lengths are specified in
    bits not bytes.

    >
    >> char keys[3][9]; /* 3 * 9 == 27 */
    >> int _pad_ : 1; /* 4 + 27 + 1 == 32, 32 % 8 == 0 */

    >
    >
    > `_pad_' happens to be safe in this context, but would
    > be unsafe in most others. Stan Brown's list of identifiers
    > to avoid
    >
    > http://www.oakroadsystems.com/tech/c-predef.htm
    >
    > is still based on the older C89 Standard and has not been
    > updated for C99, but is still helpful.

    I guess that wasn't a very good name. I just wanted to make it clear
    that that field wasn't intended to be used.

    >
    > Oh, and the `: 1' doesn't do what you seem to believe.

    Like I said above, it should have been an 8. :-/
    John Ilves, Jun 21, 2004
    #13
  14. Amarendra

    Ralmin Guest

    "Arthur J. O'Dwyer" <> wrote:
    > Hey, good idea! :)
    >
    > #include <stdio.h>
    >
    > #define PADSIZE(n) (sizeof(struct {int flag; char keys[9][3]; \
    > char pad[n];}))
    > #define PADOK(n) (PADSIZE(n)%8==0)
    > #define PAD (PADOK(1)? 1: PADOK(2)? 2: PADOK(3)? 3: PADOK(4)? 4: \
    > PADOK(5)? 5: PADOK(6)? 6: PADOK(7)? 7: PADOK(8)? 8: -1)
    >
    > typedef struct {
    > int flag;
    > char keys[9][3];
    > char padding[PAD];
    > } foo;
    >
    > (Naturally, the OP should not use this method. Nor should anyone else.)


    LCC-Win32 fails on code like this where a structure type is defined in a
    situation other than a declaration.

    Error padsize.c: 12 missing semicolon after structure declaration
    [Repeated 8 times]

    This spurious diagnostic actually triggers an "error" condition which
    prevents creation of an executable.

    On the other hand, MS VC++'s free command-line compiler also doesn't like
    your macro much, but at least only warns rather than errors out:

    padsize.c(12) : warning C4116: unnamed type definition in parentheses

    GCC, BC++ and Turbo C have no problems with your macro.

    --
    Simon.
    Ralmin, Jun 22, 2004
    #14
    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. phoenix

    structure padding

    phoenix, Mar 11, 2005, in forum: C Programming
    Replies:
    1
    Views:
    391
    Peter Nilsson
    Mar 11, 2005
  2. Replies:
    6
    Views:
    429
    Flash Gordon
    May 18, 2005
  3. Stephen Mayes

    structure padding

    Stephen Mayes, May 20, 2005, in forum: C Programming
    Replies:
    5
    Views:
    424
    Dave Thompson
    May 31, 2005
  4. ramu

    structure padding

    ramu, Feb 2, 2006, in forum: C Programming
    Replies:
    28
    Views:
    869
    Jordan Abel
    Feb 5, 2006
  5. Kislay

    Size of a structure : Structure Padding

    Kislay, Oct 1, 2007, in forum: C Programming
    Replies:
    15
    Views:
    930
    clinuxpro
    Jul 13, 2011
Loading...

Share This Page