我知道C结构中的成员与他们需要的任何边界对齐。
struct S {
uint8_t ui8;
/* invisible padding here */
uint32_t ui32;
};
我的问题是,是否定义了struct S
实例的对齐方式?
struct S my_s;
是否定义了my_s
的对齐方式?如果struct S
将ui32
作为其第一个成员,这是否重要?
我已搜索但只找到了有关struct member alignment的信息。
答案 0 :(得分:5)
是的,它会有一个对齐要求,是的,它取决于struct
成员的类型。
C11草案规范说:
完整对象类型具有对齐要求,这些要求会产生限制 在可以分配该类型的对象的地址上。
和
可以使用a查询完整类型的对齐要求
_Alignof
表达。
答案 1 :(得分:3)
答案:不在C99。在C11中是的。请参阅answer from unwind。
在所有已知平台上的C99实践中,您可以确定类型的对齐方式:
#include <stddef.h> //Defines offsetof(.,.)
#define alignmentof(TYPE) offsetof(struct { char w; TYPE v;},v)
C标准对于如何填充结构几乎没有说明,除了它没有问题,它们不能在开头填充,但可以在中间和结尾填充,并且必须在没有元素间填充的数组。
在实践中,没有人(我发现)已经提出了一个真正的平台,除了没有填充(所谓的打包)或填充最低限度以遵守底层硬件上数据类型的对齐
自然填充程序是:
sizeof
的{{1}}是最严格对齐成员对齐的倍数。如上所述,在实践中,如果发生填充,就会发生这种情况(就我的非正式调查而言)。
答案 2 :(得分:0)
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
结构使对齐等于它包含的最大尺寸成员。在这种情况下,结构将始终从地址
开始地址%4 == 0