Why doesn't C++ make the structure tighter?
例如,我有一个class,
1 2 3 4 5 6 7
| class naive {
public:
char a;
long long b;
char c;
int d;
}; |
根据我的测试程序,a到d是一个接一个的构建,比如
1 2 3
| a-------
bbbbbbbb
c---dddd |
-表示未使用。
为什么C++不能使它更紧,比如
- bbbbbbbbddddac会更紧,不必在后面加2个字节。
标准要求类和结构成员以声明它们的相同顺序存储在内存中。所以在您的示例中,d不可能出现在b之前。
而且,大多数体系结构更喜欢多字节类型在4或8字节边界上对齐。所以编译器所能做的就是在类成员之间保留空的填充字节。
您可以通过自己对成员重新排序来最小化填充,按大小顺序递增或递减。或者您的编译器可能有一个#pragma pack选项或类似的选项,它将以牺牲性能和代码大小为代价来尽量减少填充。阅读编译器的文档。
- gcc等价于#pragma pack是__attribute__ ((packed))。在C++ 11中,这是标准化的,属性EDOCX1为2。
- 具体地说,9.2.12中规定了对内存中顺序相同的数据成员的要求(未经干预的访问说明符声明的(非联合)类的非静态数据成员被分配,以便以后的成员在类对象中拥有更高的地址。ISO/IEC 14882:2003标准的[…]。
- @马蒂尼奥,你还有关于Alignas的更多信息吗?我试着用谷歌搜索,但没有得到明确的结果。这对我很有帮助。
- @基里安:你可以在最新的公开发行的标准草案:N3242中找到它。查看第7.6.2节。
- 为什么不允许编译器重新排列内存中的成员?
- @凯文-C标准是这么说的,因为这就是C标准化时的工作方式。大概是一些"聪明"的代码利用了这一点。
- @Kevin-声明带有头和可变长度主体的对象的一个常见的老派技巧是用一个长度为1(如果编译器允许的话,长度为零)的虚拟数组结束头结构,然后用malloc sizeof(头)+主体的长度。然后,可以使用虚拟数组对主体进行索引。如果可以将虚拟对象重新排序到结构的开头,那么这将不起作用。
- @Kevin:在大多数情况下,您可以将RAM区域表示为硬件寄存器、网络协议、文件格式和类似的C结构。