0
struct unaming
{
    char f;
    double dd;

    struct 
    {
    int data;
    char c;
    double d;
    };
};

I was expecting the size of this structure to be 40 bytes. But compiler returned 32 bytes. I was expecting the following layout.

[char f][7 bytes][double dd] [int data][4 bytes][char c][7bytes][double d] = 40

This was based on the rule that structures and its member variables will be aligned to the greatest size data type present.

But looks like Compiler re-ordered the unamed structured. Is that the case? Why 32 Bytes?

Anup Buchke
  • 5,210
  • 5
  • 22
  • 38
  • 3
    The assumption is wrong. The compiler didn't reorder it.This can be explained by `[char f][7 bytes][double dd][int data][char c][3 bytes][double d] = 32`. The compiler doesn't align each member to the largest alignment for a given data type. Each type has an alignment, and must be aligned to that. For primitive types like these, AFAIK, their alignments are their sizes – Justin Aug 16 '18 at 03:15
  • 1
    Test the address of individual elements in a structure instance, or step through in a debugger and view memory. See also [`alignof`](https://en.cppreference.com/w/cpp/language/alignof). – tadman Aug 16 '18 at 03:18
  • 2
    @tadman see [`offsetof`](https://en.cppreference.com/w/cpp/types/offsetof), too – Remy Lebeau Aug 16 '18 at 03:46
  • 3
    @justin: that should be an answer. – R.. GitHub STOP HELPING ICE Aug 16 '18 at 03:58
  • Further readings here in a old thread [enter link description here](https://stackoverflow.com/questions/4306186/structure-padding-and-packing) – duchonic Aug 16 '18 at 05:31

1 Answers1

6

The rule is not that each structure member must be aligned according to the greatest alignment requirement of the members in the structure. The rule is that each member must be aligned according to its own alignment requirement.

For your structure, assuming the sizes of char, int, and double are 1, 4, and 8 bytes, respectively, and assuming their alignment requirements are also 1, 4, and 8 bytes, the layout in typical C implementations is:

  • char f is at offset 0.
  • Seven bytes of padding bring the offset to 8, needed for double.
  • double dd is at offset 8.
  • The struct starts at offset 16.
  • int data is at offset 16.
  • char c is at offset 20.
  • Three bytes of padding bring the ofset to 24, needed for double.
  • double d is at offset 24.

That makes the total size 32 bytes. As that is a multiple of eight, no padding is needed at the end. (Since structures may be used in arrays, the total size of a structure needs to be a multiple of its alignment requirement so that successive structures in an array land on the desired alignment boundaries.)

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312