内部结构的拖尾填充

use*_*733 5 c language-lawyer

编译器通常在结构上插入尾部填充以在数组中使用它们时满足对齐限制:

// Size 4, alignment 2
struct A {
    uint16_t x;
    uint8_t y;
    // Padding 1 byte
};

// Size 6, alignment 2
struct B {
    struct A xy;
    uint8_t z;
    // Padding 1 byte
};
Run Code Online (Sandbox Code Playgroud)

现在考虑使用内部结构组合这些:

struct AB {
    struct {
        uint16_t x;
        uint8_t y;
    } xy;
    uint8_t z;
};
Run Code Online (Sandbox Code Playgroud)

以下可以适合4个字节,同时不会破坏对齐限制.此外,内部结构xy没有可以在别处使用的类型,因此不需要使用尾随填充.

缺点是该成员xy不兼容struct A,但没有理由说它们应该是不同的类型定义.

是否允许编译器进行此大小优化?

或者,换句话说,标准是否要求具有相同成员的2个结构总是导致相同的布局?

Pas*_*uoq 1

答案很可能是由兼容类型的概念给出的。如果t1t2是兼容类型,则可以使用指向的指针t1来访问使用 type 设置的内存t2

\n\n

在C11标准中:

\n\n
\n

6.2.7 兼容型和复合型

\n\n
    \n
  1. \xe2\x80\xa6 此外,在单独的翻译单元中声明的两个结构体、联合或枚举类型如果其标签和成员满足以下要求,则它们是兼容的:如果一个使用标签声明,则另一个应使用相同的标签声明。如果两者都在各自翻译单元内的任何位置完成,则适用以下附加要求:其成员之间应存在一一对应关系,以便每对相应成员都声明为兼容类型;如果该对中的一个成员使用对齐说明符声明,则另一个成员使用等效的对齐说明符声明;如果该对中的一个成员声明了名称,则另一个成员也声明为相同的名称。\xe2\x80\xa6
  2. \n
\n
\n\n

没有相同标签的两个结构是不兼容的类型,并且我没有看到任何强制它们具有相同布局的内容。

\n