sizeof 与 _Alignof 值

sizeof vs _Alignof value

有没有时候 _Alignof returns 的值与 sizeof 不同?例如,我尝试过的每一个都产生相同的值:

printf("%zu %zu\n", _Alignof(int), sizeof (int));
printf("%zu %zu\n", _Alignof(char), sizeof (char));

4 4
1 1

这两个值是否不同(数组除外)?

对于 struct foo { int i; char c};,许多 C 实现为 sizeof(struct foo) 生成八个,为 _Alignof(struct foo) 生成四个,因为 int 是四个字节大并且具有四个字节的对齐要求。这是因为结构必须有四字节对齐才能满足int对齐,而这需要添加三个字节的填充,所以结构大小对于int是四个字节,对于char,三个用于填充。

另一种可能是long double大小为16字节,但只需要八字节对齐。它可能是 16 字节,因为它需要那么多数据,但硬件可能只有八字节总线,因此只需要八字节对齐就可以有效地加载任何对象的部分。

类似地,任何机器通常都会有一些最严格的对齐要求 x 字节,因为它的总线是 x 字节宽或者它的处理器有一个x 的最大通用字长,因此硬件一次只能处理 x 字节的块。那么任何大于 x 字节的对象都必须由多个字组成并使用多条指令实现。对于此类对象,不需要比 x 字节更严格的对齐方式。例如,一个八字节整数可能由两个四字节对齐的四字节字组成,或者,在较旧的机器上,一个四字节整数可能由两字节对齐的两字节字组成。

对于基本类型,一个典型的例子是 32 位平台上的 long long int。它是 64 位类型,所以 8 个字节,但由两个必须单独加载和存储的 32 位字组成,因此不需要比 4 个字节更大的对齐。

Try on godbolt

他们总是不同的小案例:

  • sizeof(char[N]) == N
  • _Alignof(char[N]) == 1.

Are these two values ever different (other than with an array)?

示例差异,很可能是大字体。

printf("%zu %zu\n", sizeof(_Complex long double), _Alignof(_Complex long double));

输出(取决于实现)

32 16