sizeof(struct) giving unexpected sizes. Memory alignment issues?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MTsoul
    New Member
    • Nov 2008
    • 7

    sizeof(struct) giving unexpected sizes. Memory alignment issues?

    I noticed some quirks with C++ (not sure if this is the same for C).

    I have:

    Code:
    struct A {
        char a[14];
    };
    
    struct B {
        char b[16];
    };
    
    struct C {
        struct A a;
        struct B b;
    };
    sizeof(C) produces 32, which is mind boggling. Is the C++ compiler trying to align it to the memory structure? This is god awful for doing things like parsing an Ethernet packet, whose header is 14 bytes.

    I'm using g++ 3.4.4 on Cygwin.
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    Absolutely, C (and C++) adds padding bytes to structures so that the members in the structure are aligned onto memory boundaries that are easy for the processor to access.

    Generally this greatly speeds up any program (trying to read an unaligned word on a 16bit machine would typically take 2 byte reads a shift and an or as opposed to a single word read if the word is aligned).

    This does mean that you can not overlay any structure (especially if portability is an issue) onto data received by any stream (socket, file console and others) but that is generally a good trade off (a little complication in 1 place in the program for general efficiency) especially since endian issues may well mean you need to mess around with the data at this point anyway.

    You should read basic types (chars shorts, ints, longs plus unsigned variants) when reading from a stream remembering of course to convert from the endian of the stream (normally big endian Ethernet protocols) to the endian of your processor (little endian for Intel).

    Comment

    • MTsoul
      New Member
      • Nov 2008
      • 7

      #3
      Oh that's no fun. Is there a per-file or per-symbol compiler option to disable that? I think GCC 4 has one...

      Thanks for the confirmation though! I wish the compiler would tell me about things like this when it happens.

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        I am not familiar with the compiler you are using but a type attribute (packed) may help see Type Attributes - Using the GNU Compiler Collection (GCC).

        However as I already noted you should keep use of packed structures to a minimum to keep your code efficient which means having 2 structures 1 packed and the other unpacked and converting between them.

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          Originally posted by MTsoul
          Oh that's no fun. Is there a per-file or per-symbol compiler option to disable that? I think GCC 4 has one...
          In general, disabling the struct-padding feature may provoke an alignment-fault exception. That wouldn't happen with your particular struct; but it is likely that such a compiler option would have file-wide scope. Some other innocent struct in that file might get the alignment-faults. Another possibility is that you would be leaving a logic bomb for the poor maintenance programmer who adds another structure two years from now.

          Originally posted by MTsoul
          Thanks for the confirmation though! I wish the compiler would tell me about things like this when it happens.
          There's no reason for the compiler documentation to tell you about this. The Standard explicitly permits implementations to pad structure elements and also the overall structure itself.

          Comment

          Working...