内部结构中的尾部填充
Trailing padding in internal structure
编译器通常在结构上插入尾部填充以满足对齐
在数组中使用时的限制:
// 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
};
现在考虑使用内部结构组合这些:
struct AB {
struct {
uint16_t x;
uint8_t y;
} xy;
uint8_t z;
};
以下可以容纳 4 个字节,同时不违反对齐限制。
此外,内部结构 xy
没有可以在其他地方使用的类型,所以
不需要尾随填充。
缺点是成员 xy
与 struct A
不兼容,但有
没有理由应该像它们在不同类型定义中那样。
是否允许编译器进行这种大小优化?
或者,换句话说,标准是否要求 2 个具有相同成员的结构将始终导致相同的布局?
答案很可能由兼容类型的概念给出。如果 t1
和 t2
是兼容类型,则指向 t1
的指针可用于访问使用类型 t2
设置的内存。
在 C11 标准中:
6.2.7 Compatible type and composite type
- … Moreover, two structure, union, or enumerated types declared in separate translation units are compatible if their tags and members satisfy the following requirements: If one is declared with a tag, the other shall be declared with the same tag. If both are completed anywhere within their respective translation units, then the following additional requirements apply: there shall be a one-to-one correspondence between their members such that each pair of corresponding members are declared with compatible types; if one member of the pair is declared with an alignment specifier, the other is declared with an equivalent alignment specifier; and if one member of the pair is declared with a name, the other is declared with the same name. …
两个没有相同标签的结构是不兼容的类型,我没有看到任何强制它们具有相同布局的东西。
编译器通常在结构上插入尾部填充以满足对齐 在数组中使用时的限制:
// 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
};
现在考虑使用内部结构组合这些:
struct AB {
struct {
uint16_t x;
uint8_t y;
} xy;
uint8_t z;
};
以下可以容纳 4 个字节,同时不违反对齐限制。
此外,内部结构 xy
没有可以在其他地方使用的类型,所以
不需要尾随填充。
缺点是成员 xy
与 struct A
不兼容,但有
没有理由应该像它们在不同类型定义中那样。
是否允许编译器进行这种大小优化?
或者,换句话说,标准是否要求 2 个具有相同成员的结构将始终导致相同的布局?
答案很可能由兼容类型的概念给出。如果 t1
和 t2
是兼容类型,则指向 t1
的指针可用于访问使用类型 t2
设置的内存。
在 C11 标准中:
6.2.7 Compatible type and composite type
- … Moreover, two structure, union, or enumerated types declared in separate translation units are compatible if their tags and members satisfy the following requirements: If one is declared with a tag, the other shall be declared with the same tag. If both are completed anywhere within their respective translation units, then the following additional requirements apply: there shall be a one-to-one correspondence between their members such that each pair of corresponding members are declared with compatible types; if one member of the pair is declared with an alignment specifier, the other is declared with an equivalent alignment specifier; and if one member of the pair is declared with a name, the other is declared with the same name. …
两个没有相同标签的结构是不兼容的类型,我没有看到任何强制它们具有相同布局的东西。