结构成员和指针对齐

structure members and pointer alignment

指向结构的指针是否对齐,就好像它是指向第一个元素的指针一样?

指向结构的指针和指向其第一个成员类型(反之亦然)的指针之间的转换曾经是 UB 吗?

(我希望他们是同一个问题...)

struct element
{
    tdefa x;
    tdefb y;
}; 

int foo(struct element* e);
int bar(tdefa* a);

~~~~~

tdefa i = 0;
foo((struct element*)&i);

struct element e;
bar((tdefa*)&e);

其中 tdefatdefb 可以定义为任何类型

背景:

我问这个 一位用户在对其中一个答案的评论中提出了 C11 6.3.2.3 p7,其中指出:

"A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined"

但是我无法确定这何时会成为问题,我的理解是填充将允许结构的所有成员正确对齐。我是不是误会了?

如果:

struct element e;
tdefa* a = &e.x;

然后会起作用:

tdefa* a = (tdefa*)&e;

也会。

从来没有任何初始填充;结构的第一个成员必须从与结构本身相同的地址开始。

您始终可以通过将指针转换为整个结构来访问结构的第一个成员,使其成为指向第一个成员类型的指针。

您的 foo 示例可能 运行 会遇到麻烦,因为 foo 期望它的参数指向一个 struct element 而实际上它并没有,而且可能是对齐不匹配。

但是 bar 示例和最后一个示例很好。

指向结构的指针始终指向其初始成员。

这是直接来自 C99 standard 的引文(6.7.2.1,第 13 段),强调我的:

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning

至于你的 foobar 例子:

bar 的调用会很好,因为 bar 期望 tdefa,这正是它得到的结果。

但是,对 foo 的调用是有问题的。 foo 期望完整的 struct element,但您只传递了 tdefa(而该结构由 tdefa tdefb).