结构成员和指针对准(structure members and pointer alignment)

2019-10-21 20:19发布

是一个指向该结构排列,好像它是一个指向第一个元素?

要么

是指向一个结构和指针到它的第一部件(或反之亦然)的种类不断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指针的对象类型可以被转换为一个指针到一个不同的对象类型。如果得到的指针没有被正确用于该被引用类型对齐,该行为是未定义”

但是我无法工作了的时候,这将成为一个问题,我的理解是,填充将使该结构的所有成员正确对齐。 我误会了?

而如果:

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

将有帮助:

tdefa* a = (tdefa*)&e;

会了。

Answer 1:

从未有任何初期填补; 一个结构的第一构件是必需在相同的地址与结构本身启动。

你总是可以通过铸造指针到整个结构进入一个结构的第一个成员,是一个指向第一个成员的类型。

您的foo例如可能会遇到麻烦,因为foo将其期望参数指向一个struct element这实际上不是这样,有可能是一个定位不匹配。

但是在bar例子,最后一个例子是好的。



Answer 2:

一个指向结构总是指向它的初始成员。

这里是直接从引证C99标准 (6.7.2.1,第13段),重点煤矿:

内的结构对象,非位字段构件和单元,其中位字段驻留具有在其声明的顺序增加的地址。 一个指向结构对象,适当地转换,点到它的初始成员 (或如果该构件是一个位字段,然后到单元在其中驻留),并且反之亦然。 有可能是一个结构对象中的无名进行填充,而不是在其开始

至于你foobar的例子:

要将呼叫bar将被罚款,如bar需要一个tdefa ,这正是它变得。

调用foo ,但是,是有问题的。 foo需要一个完整的struct element ,但你只传递一个tdefa (而结构由两个tdefa tdefb )。



文章来源: structure members and pointer alignment