我想知道标准对于如何对齐和分配以下结构有什么说法:
struct A {
uint8_t b[16];
};
我可以期望A
的大小为16字节,在数组中的16字节边界上对齐(A[n]
的大小等于16*n
,例如没有填充)A
的地址将是b
的第一个元素?
为了缩小范围,我关注的平台是x86 / x64,ARM M,R,A和A50。
编辑:澄清 - 通过“对齐”我的意思是编译器如何对齐堆栈中的数组中的对象,例如每个下一个元素将是16个字节,我自然不希望malloc
在除了平台默认边界之外的任何东西上对齐。
编辑2:在阅读了答案之后,我倾向于问,我可以期望平台特定的显式对齐内在函数能够在多大程度上发挥作用?
答案 0 :(得分:1)
结构的大小至少为16.在正常的C实现中它将是16,但我没有看到C标准需要这个,没有减轻情节,例如来自用户的特殊请求。例如,如果用户使用GCC的扩展来指定结构必须具有32字节的对齐,则结构必须填充为32字节。
不能期望结构具有16的对齐要求。其成员的任何成员都没有大于1的对齐要求,并且C标准不要求结构具有比其成员更大的对齐要求。我没有看到C标准要求一个结构没有比满足其成员要求所需的最小对齐要求,因此C实现可能会给结构一个16的对齐。我是不知道没有来自用户的特殊请求的C实现。
从技术上讲,指向struct的指针不能与指向b的第一个元素的指针相同,因为前者是指向结构的指针,而后者是指向char
的指针。但是,当指向结构的指针转换为指向uint8_t [16]
的指针时,它将与(将比较等于)b
的地址相同。
在我熟悉的每个C实现中,当指向struct的指针或指向数组的指针进一步转换为指向uint8_t
的指针时,它将与(将比较等于)相同指向b
的第一个元素的指针。但是,我没有看到C标准保证这一点。当然在结构或数组的开头没有填充,所以我们知道结构的“地址”与数组的“地址”和第一个元素的“地址”相同,但这不是同样保证转换不同类型的指针会产生适当的值。