Structure Size and Padding Byte Questions

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

  1. dashley

    dashley 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.


    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.
    dashley, Oct 1, 2013
    1. Advertisements

  2. Yes, and after b and crc as well.
    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.
    No, it looks highly suspect to me on any platform. It might break from
    one compiler version to another.
    Ben Bacarisse, Oct 1, 2013
    1. Advertisements

  3. dashley

    Eric Sosman Guest

    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.
    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.
    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.
    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

    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, Oct 1, 2013
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.