Packed structs vs. unpacked structs: what's the difference?

Discussion in 'C Programming' started by Daniel Rudy, Apr 9, 2006.

  1. Daniel Rudy

    Daniel Rudy Guest

    What is the difference between packed and unpacked structs?


    --
    Daniel Rudy

    Email address has been base64 encoded to reduce spam
    Decode email address using b64decode or uudecode -m

    Why geeks like computers: look chat date touch grep make unzip
    strip view finger mount fcsk more fcsk yes spray umount sleep
     
    Daniel Rudy, Apr 9, 2006
    #1
    1. Advertising

  2. Daniel Rudy

    pemo Guest

    Daniel Rudy wrote:
    > What is the difference between packed and unpacked structs?



    If you have gcc, try this - comment out/in the #pragma pack(1) line.

    On my machine/implementation - with the pragma it outputs:

    sizeof(s1) is 10, sizeof(s2) is 10

    without the pragma:

    sizeof(s1) is 16, sizeof(s2) is 12

    Enough info for you to figure it out??


    #include <stdio.h>
    #pragma pack(1)

    typedef struct struct_1
    {
    char a;
    int b;
    char c;
    int d;

    } s1;


    typedef struct struct_2
    {
    char a;
    char c;
    int b;
    int d;

    } s2;


    int main(void)
    {
    printf("sizeof(s1) is %d, sizeof(s2) is %d\n", sizeof(s1), sizeof(s2));

    return 0;
    }

    --
    ==============
    Not a pedant
    ==============
     
    pemo, Apr 9, 2006
    #2
    1. Advertising

  3. On 2006-04-09, Daniel Rudy <> wrote:
    >
    >
    > What is the difference between packed and unpacked structs?
    >
    >


    One is packed and the other is, probably, not packed. The packed
    keyword, to the best of my knowledge, overrides compiler optimisations
    which lead to natural boundary alignment of one or more of the data
    elements contained in the structure. A "packed" structure will almost
    always have a smaller memory footprint than its unpacked brother.

    See here: http://tinyurl.com/ftv3u

    where there is a typically heated discussion on such issues.

    I have no idea on the "standardness" of "packed". but here is another
    article explaining it in the Gnu C environment:

    http://grok2.tripod.com/structure_packing.html

    --
    Aspirat primo Fortuna labori.
    -- Virgil, and all good teachers
     
    Richard G. Riley, Apr 9, 2006
    #3
  4. Daniel Rudy

    pete Guest

    Richard G. Riley wrote:
    >
    > On 2006-04-09, Daniel Rudy <> wrote:
    > >
    > >
    > > What is the difference between packed and unpacked structs?
    > >
    > >

    >
    > The packed keyword


    > I have no idea on the "standardness" of "packed".


    It's not standard C.

    --
    pete
     
    pete, Apr 9, 2006
    #4
  5. pete wrote:
    > Richard G. Riley wrote:
    > >
    > > On 2006-04-09, Daniel Rudy <> wrote:
    > > >
    > > >
    > > > What is the difference between packed and unpacked structs?
    > > >
    > > >

    > >
    > > The packed keyword

    >
    > > I have no idea on the "standardness" of "packed".

    >
    > It's not standard C.


    ....and hence should be avoided if possible. "pragma pack" and their ilk
    may slow your program at a slight saving in space and a loss of
    portability.


    --
    Nick Keighley
     
    Nick Keighley, Apr 9, 2006
    #5
  6. Daniel Rudy

    Guest

    Nick Keighley wrote:
    > pete wrote:
    > > Richard G. Riley wrote:
    > > >
    > > > On 2006-04-09, Daniel Rudy <> wrote:
    > > > >
    > > > >
    > > > > What is the difference between packed and unpacked structs?
    > > > >
    > > > >
    > > >
    > > > The packed keyword

    > >
    > > > I have no idea on the "standardness" of "packed".

    > >
    > > It's not standard C.

    >
    > ...and hence should be avoided if possible. "pragma pack" and their ilk
    > may slow your program at a slight saving in space and a loss of
    > portability.


    Pragma pack is not often used to save space. Rather it is usually used
    as a (non-portable) way to quickly "cast" a byte array (for example a
    packet) into a struct. This way you can access data within the packet
    directly by simply pointing the struct you want to the first byte of
    the packet. This trick is very common in the majority of Unix TCP/IP
    stack including Linux & BSD. It is also used in Windows TCP/IP stack
    although Microsoft has a different syntax for their version of pragma
    pack. But this, of course, is non-standard and is off topic to
    comp.lang.c.
     
    , Apr 9, 2006
    #6
  7. On 2006-04-09, Nick Keighley <> wrote:
    >
    > pete wrote:
    >> Richard G. Riley wrote:
    >> >
    >> > On 2006-04-09, Daniel Rudy <> wrote:
    >> > >
    >> > >
    >> > > What is the difference between packed and unpacked structs?
    >> > >
    >> > >
    >> >
    >> > The packed keyword

    >>
    >> > I have no idea on the "standardness" of "packed".

    >>
    >> It's not standard C.

    >
    > ...and hence should be avoided if possible. "pragma pack" and their ilk
    > may slow your program at a slight saving in space and a loss of
    > portability.
    >
    >


    Pack is their for a reason : and not, I think, generally for saving
    space. It is to enable a structure to correctly map to correct byte/word/etc
    fields in protocol packets for example. Portability is not necessarily
    an issue in these cases.

    --
    Aspirat primo Fortuna labori.
    -- Virgil, and all good teachers
     
    Richard G. Riley, Apr 9, 2006
    #7
  8. Daniel Rudy

    Jack Klein Guest

    On Sun, 9 Apr 2006 13:53:15 +0100, "pemo" <>
    wrote in comp.lang.c:

    > Daniel Rudy wrote:
    > > What is the difference between packed and unpacked structs?

    >
    >
    > If you have gcc, try this - comment out/in the #pragma pack(1) line.
    >
    > On my machine/implementation - with the pragma it outputs:
    >
    > sizeof(s1) is 10, sizeof(s2) is 10
    >
    > without the pragma:
    >
    > sizeof(s1) is 16, sizeof(s2) is 12
    >
    > Enough info for you to figure it out??
    >
    >
    > #include <stdio.h>
    > #pragma pack(1)
    >
    > typedef struct struct_1
    > {
    > char a;
    > int b;
    > char c;
    > int d;
    >
    > } s1;
    >
    >
    > typedef struct struct_2
    > {
    > char a;
    > char c;
    > int b;
    > int d;
    >
    > } s2;
    >
    >
    > int main(void)
    > {
    > printf("sizeof(s1) is %d, sizeof(s2) is %d\n", sizeof(s1), sizeof(s2));


    This of course invokes undefined behavior twice, passing a size_t to
    printf() with a conversion specifier of "%d". While the exact type of
    size_t is implementation-defined, it is guaranteed never to be a
    signed int.

    Either cast to int with "%d", or, even better, cast to unsigned long
    and use "%lu".

    And yes, there are platforms where this will break, because size_t is
    equivalent to unsigned long and long is physically larger than int.

    > return 0;
    > }


    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Apr 9, 2006
    #8
  9. Daniel Rudy

    CBFalconer Guest

    Jack Klein wrote:
    > "pemo" <> wrote in comp.lang.c:
    >

    .... snip ...
    >>
    >> int main(void)
    >> {
    >> printf("sizeof(s1) is %d, sizeof(s2) is %d\n", sizeof(s1), sizeof(s2));

    >
    > This of course invokes undefined behavior twice, passing a size_t
    > to printf() with a conversion specifier of "%d". While the exact
    > type of size_t is implementation-defined, it is guaranteed never
    > to be a signed int.
    >
    > Either cast to int with "%d", or, even better, cast to unsigned
    > long and use "%lu".
    >
    > And yes, there are platforms where this will break, because size_t
    > is equivalent to unsigned long and long is physically larger than int.
    >
    >> return 0;
    >> }


    The advantages of unbridled pedantry. The difference between
    running and non-running code is one pedant.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
     
    CBFalconer, Apr 9, 2006
    #9
  10. Daniel Rudy

    CBFalconer Guest

    "Richard G. Riley" wrote:
    > Nick Keighley <> wrote:
    >> pete wrote:
    >>> Richard G. Riley wrote:
    >>>>

    .... snip ...
    >>>>
    >>>> The packed keyword
    >>>
    >>>> I have no idea on the "standardness" of "packed".
    >>>
    >>> It's not standard C.

    >>
    >> ...and hence should be avoided if possible. "pragma pack" and
    >> their ilk may slow your program at a slight saving in space and
    >> a loss of portability.

    >
    > Pack is their for a reason : and not, I think, generally for
    > saving space. It is to enable a structure to correctly map to
    > correct byte/word/etc fields in protocol packets for example.
    > Portability is not necessarily an issue in these cases.


    However it does nothing that cannot be done in a clean portable
    manner with an array of unsigned char. Well beloved by Micro$loth
    for its ability to lock code to proprietary systems.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
     
    CBFalconer, Apr 9, 2006
    #10
  11. Daniel Rudy

    Jack Klein Guest

    On Sun, 09 Apr 2006 12:16:53 -0400, CBFalconer <>
    wrote in comp.lang.c:

    > Jack Klein wrote:
    > > "pemo" <> wrote in comp.lang.c:
    > >

    > ... snip ...
    > >>
    > >> int main(void)
    > >> {
    > >> printf("sizeof(s1) is %d, sizeof(s2) is %d\n", sizeof(s1), sizeof(s2));

    > >
    > > This of course invokes undefined behavior twice, passing a size_t
    > > to printf() with a conversion specifier of "%d". While the exact
    > > type of size_t is implementation-defined, it is guaranteed never
    > > to be a signed int.
    > >
    > > Either cast to int with "%d", or, even better, cast to unsigned
    > > long and use "%lu".
    > >
    > > And yes, there are platforms where this will break, because size_t
    > > is equivalent to unsigned long and long is physically larger than int.
    > >
    > >> return 0;
    > >> }

    >
    > The advantages of unbridled pedantry. The difference between
    > running and non-running code is one pedant.


    Chuck, this time you've just gotten too obscure for me. Are you
    agreeing with me, or with pemo?

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Apr 9, 2006
    #11
  12. Daniel Rudy

    CBFalconer Guest

    Jack Klein wrote:
    > CBFalconer <> wrote in comp.lang.c:
    >> Jack Klein wrote:
    >>> "pemo" <> wrote in comp.lang.c:
    >>>

    >> ... snip ...
    >>>>
    >>>> int main(void)
    >>>> {
    >>>> printf("sizeof(s1) is %d, sizeof(s2) is %d\n", sizeof(s1), sizeof(s2));
    >>>
    >>> This of course invokes undefined behavior twice, passing a size_t
    >>> to printf() with a conversion specifier of "%d". While the exact
    >>> type of size_t is implementation-defined, it is guaranteed never
    >>> to be a signed int.
    >>>
    >>> Either cast to int with "%d", or, even better, cast to unsigned
    >>> long and use "%lu".
    >>>
    >>> And yes, there are platforms where this will break, because size_t
    >>> is equivalent to unsigned long and long is physically larger than int.
    >>>
    >>>> return 0;
    >>>> }

    >>
    >> The advantages of unbridled pedantry. The difference between
    >> running and non-running code is one pedant.

    >
    > Chuck, this time you've just gotten too obscure for me. Are you
    > agreeing with me, or with pemo?


    You :) And taking a dig at pemos sig. And creating a new measure.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
     
    CBFalconer, Apr 9, 2006
    #12
  13. Daniel Rudy

    pemo Guest

    CBFalconer wrote:
    > Jack Klein wrote:
    >> CBFalconer <> wrote in comp.lang.c:
    >>> Jack Klein wrote:
    >>>> "pemo" <> wrote in comp.lang.c:
    >>>>
    >>> ... snip ...
    >>>>>
    >>>>> int main(void)
    >>>>> {
    >>>>> printf("sizeof(s1) is %d, sizeof(s2) is %d\n", sizeof(s1),
    >>>>> sizeof(s2));
    >>>>
    >>>> This of course invokes undefined behavior twice, passing a size_t
    >>>> to printf() with a conversion specifier of "%d". While the exact
    >>>> type of size_t is implementation-defined, it is guaranteed never
    >>>> to be a signed int.
    >>>>
    >>>> Either cast to int with "%d", or, even better, cast to unsigned
    >>>> long and use "%lu".
    >>>>
    >>>> And yes, there are platforms where this will break, because size_t
    >>>> is equivalent to unsigned long and long is physically larger than
    >>>> int.
    >>>>
    >>>>> return 0;
    >>>>> }
    >>>
    >>> The advantages of unbridled pedantry. The difference between
    >>> running and non-running code is one pedant.

    >>
    >> Chuck, this time you've just gotten too obscure for me. Are you
    >> agreeing with me, or with pemo?

    >
    > You :)


    Aw, that's a shame - for a second there I was thinking, that's one less of
    them, and one more of us!

    > And taking a dig at pemos sig. And creating a new measure.


    btw, *pemos* requires an apostrophe as it's /possessive/. Sorry - just a bit
    picky on grammar :)


    --
    ==============
    Not a pedant
    ==============
     
    pemo, Apr 9, 2006
    #13
  14. Richard G. Riley wrote:
    > On 2006-04-09, Nick Keighley <> wrote:
    > > pete wrote:
    > >> Richard G. Riley wrote:
    > >> > On 2006-04-09, Daniel Rudy <> wrote:


    > >> > > What is the difference between packed and unpacked structs?
    > >> >
    > >> > The packed keyword
    > >>
    > >> > I have no idea on the "standardness" of "packed".
    > >>
    > >> It's not standard C.

    > >
    > > ...and hence should be avoided if possible. "pragma pack" and their ilk
    > > may slow your program at a slight saving in space and a loss of
    > > portability.

    >
    > Pack is their for a reason : and not, I think, generally for saving
    > space. It is to enable a structure to correctly map to correct byte/word/etc
    > fields in protocol packets for example. Portability is not necessarily
    > an issue in these cases.


    why is portability not an issue for protocol stacks?

    --
    Nick Keighley
     
    Nick Keighley, Apr 10, 2006
    #14
  15. Daniel Rudy

    Guest

    Nick Keighley wrote:
    > Richard G. Riley wrote:
    > > On 2006-04-09, Nick Keighley <> wrote:
    > > > pete wrote:
    > > >> Richard G. Riley wrote:
    > > >> > On 2006-04-09, Daniel Rudy <> wrote:

    >
    > > >> > > What is the difference between packed and unpacked structs?
    > > >> >
    > > >> > The packed keyword
    > > >>
    > > >> > I have no idea on the "standardness" of "packed".
    > > >>
    > > >> It's not standard C.
    > > >
    > > > ...and hence should be avoided if possible. "pragma pack" and their ilk
    > > > may slow your program at a slight saving in space and a loss of
    > > > portability.

    > >
    > > Pack is their for a reason : and not, I think, generally for saving
    > > space. It is to enable a structure to correctly map to correct byte/word/etc
    > > fields in protocol packets for example. Portability is not necessarily
    > > an issue in these cases.

    >
    > why is portability not an issue for protocol stacks?


    Mainly because most things that can run TCP/IP will first make it a
    priority to port gcc. So as long as the code is as portable as gcc is
    it doesn't matter if other compilers can't use the code. Systems where
    gcc is not appropriate, such as embedded microcontrollers, tend to also
    be very resource constrained and requires a very different
    implementation of the protocol stack anyway. Actually, IMHO, the number
    one reason why the TCP/IP stack is written that way is historical. The
    BSD stack was written that way and is considered by most in the
    networking community as the canonical implementation. So you find that
    the Linux and Windows TCP/IP stack are also written using this
    nonstandard, nonportable* convention.

    * Note: It's funny to call this nonstandard practice nonportable since
    it has been ported to almost all existing OSes, Unix-like or otherwise.
    The only stupid thing is that you have to do lots of #ifdef because
    Microsoft's VC++ and gcc both have this feature but with different
    syntax.
     
    , Apr 10, 2006
    #15
  16. "" <> writes:
    > Nick Keighley wrote:
    >> Richard G. Riley wrote:

    [...]
    >> > Pack is their for a reason : and not, I think, generally for
    >> > saving space. It is to enable a structure to correctly map to
    >> > correct byte/word/etc fields in protocol packets for
    >> > example. Portability is not necessarily an issue in these cases.

    >>
    >> why is portability not an issue for protocol stacks?

    >
    > Mainly because most things that can run TCP/IP will first make it a
    > priority to port gcc. So as long as the code is as portable as gcc is
    > it doesn't matter if other compilers can't use the code. Systems where
    > gcc is not appropriate, such as embedded microcontrollers, tend to also
    > be very resource constrained and requires a very different
    > implementation of the protocol stack anyway.

    [...]

    I've used Unix systems (Cray Unicos) to which gcc has not been ported,
    and other systems (AIX, arguably Solaris) where the gcc implementation
    is not nearly as good as the "native" C compiler (or so I've heard; I
    haven't measured it myself).

    I suspect that most packet layouts are such that ordinary structure
    declarations will map to them correctly. The choice of types for the
    members won't be portable of course, but if there are no gaps within
    the packet layout, and all the components of the packet are properly
    aligned relative to the start of the packet, packing shouldn't be
    necessary. (I think.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Apr 10, 2006
    #16
    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. umberto
    Replies:
    4
    Views:
    579
    umberto
    Oct 24, 2003
  2. Chris
    Replies:
    6
    Views:
    515
    Chris Uppal
    Nov 7, 2004
  3. Replies:
    9
    Views:
    6,997
  4. A. Farber
    Replies:
    11
    Views:
    316
    Jens Thoms Toerring
    Apr 4, 2009
  5. JohnF

    packed structs

    JohnF, Sep 22, 2012, in forum: C Programming
    Replies:
    35
    Views:
    1,216
    W Karas
    Oct 16, 2012
Loading...

Share This Page