结构对齐可能会浪费内存?

H3d*_*3d9 2 c++ struct

现在我有一个 struct st,其中包含另一个结构:

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

struct st {
    char a = 1;
    st2 mySt;
    int d = 4;
    char e = 5;
};
Run Code Online (Sandbox Code Playgroud)

当我在内存中检查这个 struct st 时,它是这样的:

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
Run Code Online (Sandbox Code Playgroud)

似乎 mySt 的第一个字符按 8 对齐(在 x64 中,我认为这是使用 struct st2 的大小,并且 #pragma pack 默认为 8)。

但是,如果你让我设计编译器,我会把mySt拆开,把mySt的每个基本类型都当作st的,所以成员a和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
Run Code Online (Sandbox Code Playgroud)

那么问题来了:为什么编译器不与每个子结构中的基本类型对齐,而是与整个子结构的大小对齐?那不是浪费内存吗?

eer*_*ika 8

的所有实例都st2具有相同的布局。存储对象的位置可能不会影响该布局。对象是否为成员可能不会影响该布局。编译器不能简单地选择 的成员之一mySt并将其存储在对象之外。

考虑传入st2一个函数:

void some_function(st2&);
Run Code Online (Sandbox Code Playgroud)

该函数无法知道该对象来自何处。但它必须能够访问对象的成员。必须在编译时知道对象的布局。如果 的一个实例与另一个实例st2具有不同的布局,该函数如何知道?