是否在 C 中定义了结构类型的对齐方式?
Is alignment of struct types defined in C?
我知道 C 结构中的成员与他们需要的任何边界对齐。
struct S {
uint8_t ui8;
/* invisible padding here */
uint32_t ui32;
};
我的问题是 struct S
实例的对齐方式是否定义?
struct S my_s;
是否定义了 my_s
的对齐方式? struct S
将 ui32
作为其第一个成员是否重要?
我搜索过,但只找到关于结构成员对齐的信息。
是的,它将有对齐要求,是的,它将取决于 struct
的成员类型。
C11 规范草案说:
Complete object types have alignment requirements which place restrictions
on the addresses at which objects of that type may be allocated.
和:
The alignment requirement of a complete type can be queried using an
_Alignof
expression.
是的...
struct S {
uint8_t ui8;
/* invisible padding here */
uint32_t ui32;
};
尺码 = 8
该结构包含一个 4 字节 uint32_t 因此 struct
将对齐到 4 字节
假设它从 0x0 开始
让我们看看
0x0 = ui8
0x1 = padding
0x2 = padding
0x3 = padding
0x4 = ui32
如果假设我们在开头添加一个 uint32_t 那么它会变成......结构看起来像
struct S {
uint32_t ui32_2;
uint8_t ui8;
/* invisible padding here */
uint32_t ui32;
};
然后
0x0 = ui32_2
0x4 = ui8
0x5 = padd
0x6 = padd
0x7 = padd
0x8 = ui32
结构保持对齐等于它包含的最大大小的成员。在这种情况下,结构将始终从地址
开始
address %4 == 0
答: C99 中没有。是的,在 C11 中。参考.
在所有已知平台的实践中,在 C99 上,您可以确定类型的对齐方式:
#include <stddef.h> //Defines offsetof(.,.)
#define alignmentof(TYPE) offsetof(struct { char w; TYPE v;},v)
C 标准很少指定如何填充结构,除了它可以,它们不能在开头填充但可以在中间和末尾填充并且必须在数组中正确对齐而没有中间元素填充。
在实践中,没有人(我发现)提出一个真正的平台,除了不填充(所谓的打包)或最小填充以服从底层硬件上数据类型的对齐之外.
自然填充例程是:
- 将第一个成员放在开头(这是一个严格的要求)。
- 最少填充到下一个成员的对齐方式并插入它。
- 对所有剩余成员重复此操作。
- 最少添加结束填充以确保
struct
的 sizeof
是最严格对齐成员的对齐方式的倍数。
如前所述,实际上如果发生填充,就会发生这种情况(据我的非正式调查发现)。
我知道 C 结构中的成员与他们需要的任何边界对齐。
struct S {
uint8_t ui8;
/* invisible padding here */
uint32_t ui32;
};
我的问题是 struct S
实例的对齐方式是否定义?
struct S my_s;
是否定义了 my_s
的对齐方式? struct S
将 ui32
作为其第一个成员是否重要?
我搜索过,但只找到关于结构成员对齐的信息。
是的,它将有对齐要求,是的,它将取决于 struct
的成员类型。
C11 规范草案说:
Complete object types have alignment requirements which place restrictions on the addresses at which objects of that type may be allocated.
和:
The alignment requirement of a complete type can be queried using an
_Alignof
expression.
是的...
struct S {
uint8_t ui8;
/* invisible padding here */
uint32_t ui32;
};
尺码 = 8
该结构包含一个 4 字节 uint32_t 因此 struct
将对齐到 4 字节
假设它从 0x0 开始 让我们看看
0x0 = ui8
0x1 = padding
0x2 = padding
0x3 = padding
0x4 = ui32
如果假设我们在开头添加一个 uint32_t 那么它会变成......结构看起来像
struct S {
uint32_t ui32_2;
uint8_t ui8;
/* invisible padding here */
uint32_t ui32;
};
然后
0x0 = ui32_2
0x4 = ui8
0x5 = padd
0x6 = padd
0x7 = padd
0x8 = ui32
结构保持对齐等于它包含的最大大小的成员。在这种情况下,结构将始终从地址
开始address %4 == 0
答: C99 中没有。是的,在 C11 中。参考
在所有已知平台的实践中,在 C99 上,您可以确定类型的对齐方式:
#include <stddef.h> //Defines offsetof(.,.)
#define alignmentof(TYPE) offsetof(struct { char w; TYPE v;},v)
C 标准很少指定如何填充结构,除了它可以,它们不能在开头填充但可以在中间和末尾填充并且必须在数组中正确对齐而没有中间元素填充。
在实践中,没有人(我发现)提出一个真正的平台,除了不填充(所谓的打包)或最小填充以服从底层硬件上数据类型的对齐之外.
自然填充例程是:
- 将第一个成员放在开头(这是一个严格的要求)。
- 最少填充到下一个成员的对齐方式并插入它。
- 对所有剩余成员重复此操作。
- 最少添加结束填充以确保
struct
的sizeof
是最严格对齐成员的对齐方式的倍数。
如前所述,实际上如果发生填充,就会发生这种情况(据我的非正式调查发现)。