联合内部结构的填充如何工作?

How does padding of structs inside unions work?

我有以下内容:

#include <stdio.h>

typedef union u_data
{
        struct
        {
                int a;
                int b;
                int c;
        };
                int elem[3];
}       my_data;

int     main(void)
{
        my_data data;

        data.a = 3;
        data.b = 5;
        data.c = -3;
        printf("%d, %d, %d\n", data.elem[0], data.elem[1], data.elem[2]);
}

它按我预期的输出工作:3, 5, -3

不过我知道结构中可以有填充,这是否意味着结构中的元素可能并不总是与数组对齐?

由于填充,您不能期望abcelem数组对齐,正如您正确指出的那样。

任何依赖于相反的代码都不是可移植的 C。

does that mean that the elements in the struct might not always align with the array?

没有.

您的代码调用了未定义的行为。

数组 elem 没有义务与结构的字段对齐(由于填充)。

可以在 struct 的成员之间引入 填充 以强制执行成员的个人 对齐要求


and it works as I expected

看起来在你的情况下,成员的对齐要求已经满足,因此没有引入填充,这导致数组完美映射 struct

does that mean that the elements in the struct might not always align with the array?

否,因为可能会在 struct 的成员之间引入填充。

  • 首先,C、C11 6.5.2.3中的union有一个特殊的规则"common initial sequence":

    One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the completed type of the union is visible.

    这条规则在这里不适用,因为你的情况是一个结构和一个数组。如果它是两个结构,规则就会适用。

  • 事实上,结构可能有填充,因此如果数组与结构的对齐方式不同,则不能保证获得正确的输出。这是实现定义的行为。

  • 写入结构和从数组读取在 C(与 C++ 不同)C11 6.5.2.3/3 中很好且定义明确,因为这两种类型是兼容的。如果没有填充字节,结构只能与数组兼容。

  • "Strict aliasing"不适用于此处。

总结:这是实现定义的行为。如果编译器保证,您可能会依赖特定系统上的特定行为。代码将不可移植。