结构体的 sizeof 和 _Alignof 值

问题描述

以下哪项在标准 C 中是正确的?

(A) sizeof a 结构等于:

  1. 其最后一个成员的相对地址加上 sizeof 其最后一个成员。 (我知道这不可能是真的。)

  2. 其最后一个成员的相对地址加上其最后一个成员的对齐值(由 _Alignof 运算符获得)。 (这也不能为真,因为在某些情况下,sizeof 类型可能大于其 _Alignof 值。请参阅 32 位 Windows GCC 中的 long doublesizeof 是 12,_Alignof 是 4。)

  3. 其最后一个成员的相对地址加上结构本身的对齐值。 (这也不能成立,正如在前面的陈述中所解释的。)

  4. 其最后一个成员的相对地址加上最后一个成员的最大大小和结构本身的对齐值。

  5. 别的东西。

相对地址我的意思是它的最后一个成员的起始字节与其第一个成员(或结构本身)的起始字节之间的距离,可以用 offsetof像这样的宏:offsetof(struct st,last_member)


(B) 结构体的 _Alignof 值等于:

  1. 成员的 _Alignof 值具有最大的 _Alignof 值。

  2. 别的东西。


注意事项:

  • 我不是在谈论在特定环境中的具体实现,而是在讨论符合 “标准 C (C18)” 的实现在理论上应该如何表现。

  • _Alignof 是标准的 C 运算符,alignof 是它在 stdalign.h 标头中定义的宏同义词。

解决方法

A 的答案是“别的东西”。

结构的大小必须至少是其最后一个成员的偏移量加上该成员的大小加上足够的填充字节以使结构的大小成为其对齐要求的倍数(等于其任何一个的最大对齐要求)会员)。 C 实现可能会以对齐要求的倍数添加额外的填充字节,尽管我知道没有这样做。

B 的答案是结构的对齐要求(其 npx tsc src/* 值)等于其成员的最严格对齐要求(其中最大的 _Alignof 值)。

特别要注意 C 2018 6.2.7 4 说“……每个有效的对齐值都应该是 2 的非负整数幂。”因此,如果任何对齐满足最严格的成员对齐要求,则它满足每个成员对齐要求,因此是足够的。