c++ 为什么这个结构填充技巧工作?

考虑这个简单的程序

#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

我也注意到一些奇怪的cl的结构转储。如果我们要求没有尾部填充的数据大小(“dsize”),

          A   B
first     8   9
second    7   8

那么在第一个例子中我们得到dsize(A)== 8.为什么这不是7?

最佳答案
我不是一个真正的语言律师C,但是我发现到目前为止:

参考this question中的答案,一个结构体只保留一个标准布局POD,而只有一个类本身和它的父类中有非静态成员。所以在这个想法A有一个保证的布局在两种情况下,但B不在任何一种情况。

支持这一点的事实是,std::is_pod对于A是真的,对于B两者都是假的。

>第一种情况:http://ideone.com/jyPb5J
>第二种情况:http://ideone.com/bYcLXa

因此,如果我自己正确理解这一点,编译器允许一些空间做它想要与B的布局在这两种情况下。并且显然在第二种情况下,它感觉像利用了否则将是A的填充字节。

转载注明原文:c++ 为什么这个结构填充技巧工作? - 代码日志