struct padding

Discussion in 'C Programming' started by edware, Apr 25, 2006.

  1. edware

    edware Guest

    I want to read header data from a image file,
    and I have a struct that represent this header.
    But it seems like my compiler pads the data,
    resulting that my fread() call won't put the right
    things in the right place.

    The struct starts like this:

    struct header {
    char magic[2]; /* 2 bytes */
    uint32_t size; /* 4 bytes */
    ...
    };

    It seems like my compiler puts two extra
    bytes after the magic field, which will
    result in a wrong size value.

    Is there some standard way to disable the padding?
     
    edware, Apr 25, 2006
    #1
    1. Advertising

  2. edware wrote:
    > I want to read header data from a image file,
    > and I have a struct that represent this header.
    > But it seems like my compiler pads the data,
    > resulting that my fread() call won't put the right
    > things in the right place.
    >
    > The struct starts like this:
    >
    > struct header {
    > char magic[2]; /* 2 bytes */
    > uint32_t size; /* 4 bytes */
    > ...
    > };
    >
    > It seems like my compiler puts two extra
    > bytes after the magic field, which will
    > result in a wrong size value.
    >
    > Is there some standard way to disable the padding?

    Well, since the padding itself is compiler-dependant, the answer is
    likely no.

    Why do you care about padding?
     
    Andrew Poelstra, Apr 25, 2006
    #2
    1. Advertising

  3. edware

    Ian Collins Guest

    edware wrote:
    > I want to read header data from a image file,
    > and I have a struct that represent this header.
    > But it seems like my compiler pads the data,
    > resulting that my fread() call won't put the right
    > things in the right place.
    >
    > The struct starts like this:
    >
    > struct header {
    > char magic[2]; /* 2 bytes */
    > uint32_t size; /* 4 bytes */
    > ...
    > };
    >
    > It seems like my compiler puts two extra
    > bytes after the magic field, which will
    > result in a wrong size value.
    >
    > Is there some standard way to disable the padding?


    No.

    Your compiler might have an option, if you hardware platform supports it.

    --
    Ian Collins.
     
    Ian Collins, Apr 25, 2006
    #3
  4. edware

    edware Guest

    Andrew Poelstra wrote:
    > edware wrote:
    >> I want to read header data from a image file,
    >> and I have a struct that represent this header.
    >> But it seems like my compiler pads the data,
    >> resulting that my fread() call won't put the right
    >> things in the right place.
    >>
    >> The struct starts like this:
    >>
    >> struct header {
    >> char magic[2]; /* 2 bytes */
    >> uint32_t size; /* 4 bytes */
    >> ...
    >> };
    >>
    >> It seems like my compiler puts two extra
    >> bytes after the magic field, which will
    >> result in a wrong size value.
    >>
    >> Is there some standard way to disable the padding?

    > Well, since the padding itself is compiler-dependant, the answer is
    > likely no.
    >
    > Why do you care about padding?


    I care about it because it ruins things for me when I read
    the whole structure with a fread() call. Is it better
    to read and write each member of the struct individually?

    Thanks for the help
     
    edware, Apr 26, 2006
    #4
  5. edware <> writes:
    > I want to read header data from a image file,
    > and I have a struct that represent this header.
    > But it seems like my compiler pads the data,
    > resulting that my fread() call won't put the right
    > things in the right place.
    >
    > The struct starts like this:
    >
    > struct header {
    > char magic[2]; /* 2 bytes */
    > uint32_t size; /* 4 bytes */
    > ...
    > };
    >
    > It seems like my compiler puts two extra
    > bytes after the magic field, which will
    > result in a wrong size value.
    >
    > Is there some standard way to disable the padding?


    No. See question 2.12 in the comp.lang.c FAQ, <http://c-faq.com/>.

    If the header in the file really contains a 2-byte magic number,
    immediately followed by a 4-byte unsigned integer, the best approach
    is probably to read it as an array of 6 bytes, then extract the bytes
    you want, perhaps using memcpy(). You should also think about byte
    ordering; is the size field stored high-order byte first or low-order
    byte first?

    --
    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 26, 2006
    #5
  6. edware

    Flash Gordon Guest

    Andrew Poelstra wrote:
    > edware wrote:
    >> I want to read header data from a image file,
    >> and I have a struct that represent this header.
    >> But it seems like my compiler pads the data,
    >> resulting that my fread() call won't put the right
    >> things in the right place.
    >>
    >> The struct starts like this:
    >>
    >> struct header {
    >> char magic[2]; /* 2 bytes */


    unsigned char would probably be better. char could be either signed or
    unsigned.

    >> uint32_t size; /* 4 bytes */
    >> ...
    >> };
    >>
    >> It seems like my compiler puts two extra
    >> bytes after the magic field, which will
    >> result in a wrong size value.
    >>
    >> Is there some standard way to disable the padding?

    > Well, since the padding itself is compiler-dependant, the answer is
    > likely no.


    The answer is definitely no.

    The best method is to read the data a byte at a time and reconstruct the
    structures. This also avoids problems with endienness. For strict
    portability you should be aware that a byte (and thus a char) may be
    more than 8 bits!

    > Why do you care about padding?


    He already provided that information!
    --
    Flash Gordon, living in interesting times.
    Web site - http://home.flash-gordon.me.uk/
    comp.lang.c posting guidelines and intro:
    http://clc-wiki.net/wiki/Intro_to_clc
     
    Flash Gordon, Apr 26, 2006
    #6
  7. edware wrote:
    > Andrew Poelstra wrote:
    >> edware wrote:
    >>> I want to read header data from a image file,
    >>> and I have a struct that represent this header.
    >>> But it seems like my compiler pads the data,
    >>> resulting that my fread() call won't put the right
    >>> things in the right place.
    >>>
    >>> The struct starts like this:
    >>>
    >>> struct header {
    >>> char magic[2]; /* 2 bytes */
    >>> uint32_t size; /* 4 bytes */
    >>> ...
    >>> };
    >>>
    >>> It seems like my compiler puts two extra
    >>> bytes after the magic field, which will
    >>> result in a wrong size value.
    >>>
    >>> Is there some standard way to disable the padding?

    >> Well, since the padding itself is compiler-dependant, the answer is
    >> likely no.
    >>
    >> Why do you care about padding?

    >
    > I care about it because it ruins things for me when I read
    > the whole structure with a fread() call. Is it better
    > to read and write each member of the struct individually?
    >
    > Thanks for the help


    Yes; that way when your struct changes, you won't have to recreate all
    your files.

    You should also use text files instead of binary for portability reasons.
     
    Andrew Poelstra, Apr 26, 2006
    #7
  8. edware

    Richard Bos Guest

    edware <> wrote:

    > Andrew Poelstra wrote:
    > > edware wrote:
    > >> struct header {
    > >> char magic[2]; /* 2 bytes */
    > >> uint32_t size; /* 4 bytes */
    > >> ...
    > >> };
    > >>
    > >> It seems like my compiler puts two extra
    > >> bytes after the magic field, which will
    > >> result in a wrong size value.


    > > Why do you care about padding?

    >
    > I care about it because it ruins things for me when I read
    > the whole structure with a fread() call. Is it better
    > to read and write each member of the struct individually?


    Better, yes, since there's no portable way to guarantee that the layout
    of a struct in memory matches that of a file record.
    The best way to read binary records, though, is often to read the whole
    thing into a buffer of unsigned chars using fread(), and then to copy
    the values into the desired struct members using shifts and bitwise
    operators. To write, do the opposite: use shifts and bitwise ops to move
    values of a struct member into the required bytes of an unsigned char
    array, and then write the whole thing using fwrite().

    Richard
     
    Richard Bos, Apr 26, 2006
    #8
  9. edware

    Eric Sosman Guest

    Richard Bos wrote:
    > edware <> wrote:
    >
    >
    >>Andrew Poelstra wrote:
    >>
    >>>edware wrote:
    >>>
    >>>>struct header {
    >>>> char magic[2]; /* 2 bytes */
    >>>> uint32_t size; /* 4 bytes */
    >>>> ...
    >>>>};
    >>>>
    >>>>It seems like my compiler puts two extra
    >>>>bytes after the magic field, which will
    >>>>result in a wrong size value.

    >
    >
    >>>Why do you care about padding?

    >>
    >>I care about it because it ruins things for me when I read
    >>the whole structure with a fread() call. Is it better
    >>to read and write each member of the struct individually?

    >
    >
    > Better, yes, since there's no portable way to guarantee that the layout
    > of a struct in memory matches that of a file record.
    > The best way to read binary records, though, is often to read the whole
    > thing into a buffer of unsigned chars using fread(), and then to copy
    > the values into the desired struct members using shifts and bitwise
    > operators. To write, do the opposite: use shifts and bitwise ops to move
    > values of a struct member into the required bytes of an unsigned char
    > array, and then write the whole thing using fwrite().


    An added benefit of this approach is that it becomes
    easier to deal with other issues affecting data exchange,
    such as endianness, differing notions of how big an `int'
    is, different floating-point representations, and so on.
    Divorcing the external format from the internal format is
    not just about avoiding alignment hassles, but has other
    advantages as well.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Apr 26, 2006
    #9
  10. edware

    Ed Vogel Guest

    "edware" <> wrote in message
    news:UKx3g.54370$...
    >I want to read header data from a image file,
    > and I have a struct that represent this header.
    > But it seems like my compiler pads the data,
    > resulting that my fread() call won't put the right
    > things in the right place.
    >
    > The struct starts like this:
    >
    > struct header {
    > char magic[2]; /* 2 bytes */
    > uint32_t size; /* 4 bytes */
    > ...
    > };
    >
    > It seems like my compiler puts two extra
    > bytes after the magic field, which will
    > result in a wrong size value.
    >
    > Is there some standard way to disable the padding?


    As others have stated, there is no standard way to do this.
    However, many compilers have #pragma directives or command
    line switches to turn off the padding. While not strictly portable,
    this might be a good choice to consider.

    Ed
     
    Ed Vogel, Apr 27, 2006
    #10
    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. Chris Fogelklou
    Replies:
    36
    Views:
    1,433
    Chris Fogelklou
    Apr 20, 2004
  2. Hallvard B Furuseth

    Padding bits and struct assignment

    Hallvard B Furuseth, Dec 27, 2006, in forum: C Programming
    Replies:
    5
    Views:
    679
    Eric Sosman
    Dec 27, 2006
  3. Replies:
    11
    Views:
    895
  4. vikas talwar

    struct padding ???

    vikas talwar, May 31, 2008, in forum: C Programming
    Replies:
    3
    Views:
    463
    Keith Thompson
    May 31, 2008
  5. Replies:
    13
    Views:
    378
    glen herrmannsfeldt
    May 5, 2013
Loading...

Share This Page