Structure Size and Padding Byte Questions

Discussion in 'C Programming' started by dashley@gmail.com, Oct 1, 2013.

  1. Guest

    I have the following constructs:

    typedef struct
    {
    unsigned char a[3];
    unsigned short b; //Presumed 16 bits
    unsigned char crc;
    } mystruct;

    mystruct x;

    ....

    x.crc = CalculateCrc8(&x, sizeof(x) - 1);
    //Designed to exclude CRC from CRC calculation.

    I'm not sure if the compiler is C90 or C99.

    Questions:

    a)I'm assuming that the compiler is free to insert a padding byte after x.a?

    b)I'm assuming that if you obtain the memory for the structure as an automatic or via malloc(), the padding byte could have any value, and only a block memory operation such as memset() set it to 0?

    c)Is the CRC calculation call -- especially the use of "sizeof() - 1" in this way -- valid on all platforms? Specifically, can the compiler insert structure padding bytes AFTER x.crc so that subtracting 1 from sizeof() won'thave the desired effect of excluding the CRC itself from the CRC calculation?

    Thanks for any information, especially about what is guaranteed behavior and not guaranteed behavior.
    , Oct 1, 2013
    #1
    1. Advertising

  2. writes:

    > I have the following constructs:
    >
    > typedef struct
    > {
    > unsigned char a[3];
    > unsigned short b; //Presumed 16 bits
    > unsigned char crc;
    > } mystruct;
    >
    > mystruct x;
    >
    > ...
    >
    > x.crc = CalculateCrc8(&x, sizeof(x) - 1);
    > //Designed to exclude CRC from CRC calculation.
    >
    > I'm not sure if the compiler is C90 or C99.
    >
    > Questions:
    >
    > a)I'm assuming that the compiler is free to insert a padding byte
    > after x.a?


    Yes, and after b and crc as well.

    > b)I'm assuming that if you obtain the memory for the structure as an
    > automatic or via malloc(), the padding byte could have any value, and
    > only a block memory operation such as memset() set it to 0?


    The padding can have any value with other allocations as well. What's
    more it can acquire any value due valid operations on members of the
    struct. For example, setting x.b = 1 could alter any or all of the
    padding bytes.

    > c)Is the CRC calculation call -- especially the use of "sizeof() - 1"
    > in this way -- valid on all platforms?


    No, it looks highly suspect to me on any platform. It might break from
    one compiler version to another.

    > Specifically, can the compiler
    > insert structure padding bytes AFTER x.crc so that subtracting 1 from
    > sizeof() won't have the desired effect of excluding the CRC itself
    > from the CRC calculation?


    Yes.

    > Thanks for any information, especially about what is guaranteed
    > behavior and not guaranteed behavior.


    --
    Ben.
    Ben Bacarisse, Oct 1, 2013
    #2
    1. Advertising

  3. Eric Sosman Guest

    On 10/1/2013 11:09 AM, wrote:
    > I have the following constructs:
    >
    > typedef struct
    > {
    > unsigned char a[3];
    > unsigned short b; //Presumed 16 bits
    > unsigned char crc;
    > } mystruct;
    >
    > mystruct x;
    >
    > ...
    >
    > x.crc = CalculateCrc8(&x, sizeof(x) - 1);
    > //Designed to exclude CRC from CRC calculation.
    >
    > I'm not sure if the compiler is C90 or C99.
    >
    > Questions:
    >
    > a)I'm assuming that the compiler is free to insert a padding byte after x.a?


    Yes. Also after x.b (although that's unlikely) and after x.crc
    (more likely than not). The only place where there definitely won't
    be a padding byte is *before* x.a.

    > b)I'm assuming that if you obtain the memory for the structure as an automatic or via malloc(), the padding byte could have any value, and only a block memory operation such as memset() set it to 0?


    Yes. Even if you memset() the entire struct to zero (or any
    other value), padding bytes are not guaranteed to retain that value
    when other operations are performed on the struct. Store something
    in a a struct element, and padding bytes may change "spontaneously."
    Assign one struct to another, and the padding bytes of the destination
    need not match those of the source.

    > c)Is the CRC calculation call -- especially the use of "sizeof() - 1" in this way -- valid on all platforms? Specifically, can the compiler insert structure padding bytes AFTER x.crc so that subtracting 1 from sizeof() won't have the desired effect of excluding the CRC itself from the CRC calculation?


    It's (potentially) invalid, because as you suspect the compiler
    may insert padding after x.crc. Instead, you could use

    #include <stddef.h>
    ...
    x.crc = CalculateCrc8(&x, offsetof(mystruct, crc));

    .... but you'd still have all the problems associated with any padding
    prior to the crc element.

    > Thanks for any information, especially about what is guaranteed behavior and not guaranteed behavior.


    There are few guarantees about padding bytes. They *have*
    values, and you can observe (and change) them by treating the
    struct as an array of char. However, operations on the struct's
    "payload" elements are not guaranteed to leave the padding bytes
    intact.

    The usual reason for CRC's and so on is to improve detection
    of transcription errors: When you send data from one system to
    another, or when you store it in a file and read it back again,
    you'd like to use a CRC to increase your confidence that the data
    hasn't been mangled somewhere along the line. Therefore, you
    usually want to calculate a CRC not for the struct your program
    uses to manipulate the data, but for the byte stream that encodes
    the data for reading and writing. If you write this way:

    Copy the "payload" data from the struct to an array
    of bytes,
    Calculate and append a CRC or other checksum,
    Write the entire blob

    .... and read this way:

    Read the blob into an array of bytes,
    Calculate and verify the CRC or checksum,
    Extract the data into a struct for the program's use

    .... then you won't have to worry about padding and such. (This
    also gives you a convenient hook for dealing with representation
    issues, like endianness mismatches.)

    --
    Eric Sosman
    d
    Eric Sosman, Oct 1, 2013
    #3
    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. Amarendra

    Structure padding.

    Amarendra, Jun 21, 2004, in forum: C Programming
    Replies:
    13
    Views:
    9,561
    Ralmin
    Jun 22, 2004
  2. phoenix

    structure padding

    phoenix, Mar 11, 2005, in forum: C Programming
    Replies:
    1
    Views:
    395
    Peter Nilsson
    Mar 11, 2005
  3. Replies:
    6
    Views:
    434
    Flash Gordon
    May 18, 2005
  4. Kislay

    Size of a structure : Structure Padding

    Kislay, Oct 1, 2007, in forum: C Programming
    Replies:
    15
    Views:
    934
    clinuxpro
    Jul 13, 2011
  5. Shivanand Kadwadkar

    Structure byte padding rule

    Shivanand Kadwadkar, Feb 24, 2011, in forum: C Programming
    Replies:
    11
    Views:
    601
    Tim Rentsch
    Mar 11, 2011
Loading...

Share This Page