2
votes

Now I have a struct st, which contains another struct inside:

struct st2 {
    char b = 2;
    long c = 3;
};

struct st {
    char a = 1;
    st2 mySt;
    int d = 4;
    char e = 5;
};

When I check this struct st in memory, it was as follows:

0x7fffffffdce0: 0x01    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7fffffffdce8: 0x02    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7fffffffdcf0: 0x03    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7fffffffdcf8: 0x04    0x00    0x00    0x00    0x05    0x00    0x00    0x00

It seems that mySt's first char is aligned by 8 (in x64, I think that's using size of struct st2, and #pragma pack is defaulted to 8).

However, if you let me design the compiler, I will take mySt apart and treat mySt's each basic type as st's, so there should be no padding between member a and b:

struct st {
    char a = 1;
    char b = 2;  // unwind mySt
    long c = 3;  // unwind mySt
    int d = 4;
    char e = 5;
};

// Now the char a and b can storage in just one qword, by unwinding the sub structure.
0x7fffffffdcf0: 0x01    0x02    0x00    0x00    0x00    0x00    0x00    0x00
0x7fffffffdcf8: 0x03    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7fffffffdd00: 0x04    0x00    0x00    0x00    0x05    0x00    0x00    0x00

So here is the question: Why the compiler did not align with the basic type in each sub-structure, but align with the whole sub-structure's size? Isn't that a waste of memory?

1

1 Answers

8
votes

All instances of st2 have the same layout. Where the object is stored may not affect that layout. Whether the object is a member or not may not affect that layout. The compiler cannot simply pick one of the members of mySt and store it outside of the object.

Consider passing st2 into a function:

void some_function(st2&);

That function cannot know where that object comes from. But it has to be able to access the members of the object. The layout of the object has to be known at compile time. If one instance of st2 would have different layout from another, how would the function know?