【发布时间】:2015-09-24 07:17:45
【问题描述】:
考虑这个简单的程序
#include <iostream>
struct A
{
int x1234;
short x56;
char x7;
};
struct B : A
{
char x8;
};
int main()
{
std::cout << sizeof(A) << ' ' << sizeof(B) << '\n';
return 0;
}
这打印出8 12。尽管B 可以在不破坏对齐要求的情况下打包成 8 个字节,但它却占用了 12 个字节。
如果有sizeof(B) == 8 会很好,但答案是
Is the size of a struct required to be an exact multiple of the alignment of that struct? 表示没有办法。
因此,当以下情况发生时,我感到很惊讶
struct MakePackable
{
};
struct A : MakePackable
{
int x1234;
short x56;
char x7;
};
struct B : A
{
char x8;
};
打印8 8。
这里发生了什么?我怀疑标准布局类型与它有关。如果是这样,那么导致上述行为的原因是什么,而该功能的唯一目的是确保与 C 的二进制兼容性?
编辑:正如其他人指出的那样,这是 ABI 或编译器特定的,所以我应该补充一点,在使用以下编译器的 x86_64-unknown-linux-gnu 上观察到了这种行为:
- clang 3.6
- gcc 5.1
我还从 clang 的 struct dumper 中发现了一些奇怪的东西。如果我们要求没有尾部填充(“dsize”)的数据大小,
A B
first 8 9
second 7 8
那么在第一个例子中我们得到dsize(A) == 8。为什么不是 7?
【问题讨论】:
-
也许除了编译器实现细节之外没有其他理由......
-
您将不得不询问特定的 ABI,因为这种行为在 C++ 本身范围内的可能性几乎为零。 FWIW,我在 Itanium 中找不到任何东西(一目了然)来解释这一点,尽管我确实在 GCC 5.1 中得到了
8 8,所以...:/ -
标签language-lawyer适合这个问题吗?
-
我得到
8 12用于VS2013下的第二个代码sn-p,它似乎是特定于编译器实现的。 -
这是特定于您的编译器的。一个非常相似的案例是described here。
标签: c++ inheritance padding