【问题标题】:structure members and pointer alignment结构成员和指针对齐
【发布时间】:2015-02-09 20:30:11
【问题描述】:

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

在指向结构的指针和指向其第一个成员(反之亦然)的类型的指针之间是否存在转换?

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

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 可以定义为任何类型

背景:

我问过这个question 一位用户在评论其中一个答案时提出了 C11 6.3.2.3 p7 声明:

"指向对象类型的指针可以转换为指向对象类型的指针 不同的对象类型。如果结果指针不正确 为引用的类型对齐,行为未定义”

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

如果:

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

然后会起作用:

tdefa* a = (tdefa*)&e;

也会。

【问题讨论】:

    标签: c pointers struct


    【解决方案1】:

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

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

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

    不过bar 的例子和最后的例子都很好。

    【讨论】:

    • 即使foo1 只使用了结构的第一个元素?如果是这样,请您详细说明“麻烦”,谢谢!
    • @jayjay 这个问题出现了here
    • @jayjay 你的两个问题是不同的,我的意思是你刚才在这个评论中问的问题是关于你的另一个问题的问题!这个问题也在问几个不同的事情。
    • 无论类型是什么,对foo 的调用都可能出现对齐错误,即使没有对齐错误,一旦我们进入foo 然后(请参阅其他问题进行讨论)
    • @jayjay struct S { char c; int d; } :整个结构可能与int 具有相同的对齐方式,并且cd 之间可能会有填充。如果您写char ch;,那么(S *)&c 可能会触发对齐错误,因为ch 可能没有恰好与int 正确对齐。在这种情况下。
    【解决方案2】:

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

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

    在结构对象中,非位域成员和位域所在的单元的地址按声明顺序递增。 一个指向结构对象的指针,经过适当的转换,指向它的初始成员(或者如果该成员是位域,则指向它所在的单元),反之亦然。结构对象中可能有未命名的填充,但不是在其开头

    至于您的foobar 示例:

    调用bar 会很好,因为bar 需要tdefa,这正是它所得到的。

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

    【讨论】:

      猜你喜欢
      • 2017-02-27
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-26
      • 1970-01-01
      相关资源
      最近更新 更多