为什么C++不让结构更紧凑?

31
例如,我有一个
class naive {
public:
    char a;
    long long b;
    char c;
    int d;
};

根据我的测试程序,ad 是依次构建的,就像这样。
a-------
bbbbbbbb
c---dddd

- 表示未使用。

为什么C++不像这样更紧凑呢?

ac--dddd
bbbbbbbb

5
bbbbbbbbddddac 可以更加紧凑,你不需要在后面填充两个字节。 - phuclv
你必须在任何情况下都要填充2个字节,以满足整个结构的对齐要求。@phuclv - MrIo
1个回答

56

根据标准规定,类和结构的成员必须按照声明的顺序存储在内存中。因此,在您的示例中,d 不可能出现在 b 之前。

此外,大多数架构都希望多字节类型在4或8个字节的边界上对齐。所以编译器能做的就是在类成员之间留下空的填充字节。

您可以通过自行按大小递增或递减的顺序重新排序成员来最小化填充。或者您的编译器可能有一个 #pragma pack选项或类似的选项,该选项将尝试在可能牺牲性能和代码大小的情况下最小化填充。请阅读您的编译器文档。


12
GCC中#pragma pack的等效写法是__attribute__((packed))。在C++11中,通过属性alignas来实现标准化。请注意,翻译保持了原文的意思和技术术语,但尽可能地使其更加通俗易懂。 - R. Martinho Fernandes
8
具体而言,数据成员须按同样顺序存储在内存中的要求已经在 ISO/IEC 14882:2003 标准的 9.2.12(非联合类声明的非静态数据成员未插入访问说明符时,后续成员在类对象中的地址较高[...])中被规范化。 - Martin Sojka
3
C标准如此规定,因为在C标准化时它就是这样工作的。可能有一些“聪明”的代码利用了这一点。 - Bo Persson
7
声明具有标题和可变长度正文的对象的一个常见老派技巧是以长度为一的虚拟数组结束标题结构(如果编译器允许,则长度为零),然后动态分配 sizeof(header)+length_of_body 的空间。您可以使用虚拟数组对正文进行索引。如果虚拟数组可以重新排序到结构的开头,这种方法就不起作用了。 - Russell Borogove
6
大多数情况下,你可以用C语言结构体来表示映射到硬件寄存器、网络协议、文件格式和类似结构的RAM区域。 - Martin Sojka
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接