包含打包结构的结构是否自行包装?

时间:2018-05-09 23:46:49

标签: c++ struct packing

假设我有一个包含其他结构的结构,这些结构未打包:

struct ContainerOfNonPacked
{
    NonPacked1 first;
    NonPacked2 second;
};

然后我有一个包含其他结构的结构:

struct ContainerOfPacked
{
    Packed1 first; // declaration of struct had __attribute__((packed))
    Packed2 second; // ditto
};

第一个不会由编译器打包(即,不能保证在结构内部没有"空洞")。它可能巧合地没有漏洞,但这不是问题所在。

第二个包含包装结构的容器怎么样?是否有任何保证单独由打包结构组成的结构作为其字段本身是否已打包?

1 个答案:

答案 0 :(得分:0)

编辑:由编译器决定,并不是一个可以依赖的行为。

对于GCC和clang的情况,仅包含打包结构的结构本身就是“#34;”#34;。他们不会有任何填充物和孔#34;在他们中间。

以下是一个示例(godbolt链接:https://godbolt.org/g/2noSpP):

我们有四个结构,Packed1,Packed2,NonPacked1和NonPacked2。

#include <cstdint>

struct Packed1
{
    uint32_t a;
    uint64_t b;
} __attribute__((packed));

struct NonPacked1
{
    uint16_t a;
    // Padding of 2 bytes
    uint32_t b;
    uint8_t c;
};

// We have two structs of the same size, one packed and one not
static_assert(sizeof(NonPacked1) == 12);
static_assert(sizeof(Packed1) == 12);

struct Packed2
{
    uint64_t a;
    uint64_t b;
} __attribute__((packed)); // packing has no effect, but better for illustration

struct NonPacked2
{
    uint32_t a;
    // Padding of 4 bytes
    uint64_t b;
};

// And again, two structs of the same size
static_assert(sizeof(Packed2) == 16);
static_assert(sizeof(NonPacked2) == 16);

Packed1和Packed2进入ContainerOfPacked结构,另外两个进入ContainerOfNonPacked。

struct ContainerOfNonPacked
{
    NonPacked1 first; // 12 bytes
    // Padding of 4 bytes between the non-packed struct-fields
    NonPacked2 second; // 16 bytes
};

struct ContainerOfPacked
{
    Packed1 first; // 12
    // No padding between the packed struct-fields
    Packed2 second; // 16
};

static_assert(sizeof(ContainerOfNonPacked) == 32);
static_assert(sizeof(ContainerOfPacked) == 28);

正如代码注释和静态断言所示,压缩结构的容器内部没有填充孔。它表现得好像它本身就是#34;打包的#34;。

虽然这是一个答案,但我也在寻找可以引用标准相关部分或其他权威/理论解释的答案。