3

有些书说是,但下面的代码表明它不是真的

union
{
     int n;
     char array[5];
} u;
printf("%d %d %d", sizeof(u.n), sizeof(u.array), sizeof(u));

你怎么看?

4

5 回答 5

3

联合体的大小必须满足两个要求:

  • 它必须至少与其最大的成员一样大
  • 它必须是其每个成员的对齐要求的倍数。

需要后一条规则才能使数组起作用;当一个接一个地放置在内存中时,它可以保持联合正确对齐。

因此,如果最大元素是五个字节,但某些元素需要四字节对齐,则联合大小必须是大于或等于五个字节的四个字节的倍数。八个字节满足了这一点。

大多数 C 实现使用符合这两个规则的最小尺寸。

于 2013-09-12T13:35:18.740 回答
2

在这种情况下,联合在 32 位机器上与 4 个字节对齐(或在 64 位机器上与 8 个字节对齐),因此它在内存中看起来像这样:

11 11 11 11
11 XX XX XX
   ^   ^  ^
   3 padded bytes

因此,为了对齐添加了额外的三个字节,这使得大小为 8。如果要更改此行为,您需要将其打包为 1 个字节:

#pragma pack(1)
union
{
     int n;
     char array[5];
} u;
#pragma pack()

现在联合的大小正好是 5,看起来像:

11 11 11 11
11
于 2013-09-12T08:47:28.517 回答
2

查看Cx0 标准,它说:

工会的规模足以容纳其最大的成员

因此,您不能依赖大小等于最大成员的大小。是否开启取决于编译器实现、使用的标志等。

于 2013-09-12T07:50:13.420 回答
1

编译器通常根据对齐要求确定大小。在您的情况下,最大成员的大小是 5 并且对齐它使其成为 8。这是必需的,因为您可以声明此联合类型的数组。

于 2013-09-12T08:01:52.373 回答
1

该标准只保证a的大小union对于最大的成员是足够的,即不一定是相同的大小。

C11 6.7.2.1 结构和联合说明符

a 的大小union足以包含其最大的成员。任何时候最多可以将其中一个成员的值存储在联合对象中。一个指向union对象的指针,经过适当的转换,指向它的每个成员(或者如果一个成员是一个位域,那么指向它所在的单元),反之亦然。


当我在我的机器上运行您的示例时,输出是4 5 8,可能 的大小union被填充为机器字的倍数,就像struct.

于 2013-09-12T08:10:27.270 回答