将嵌套struct作为其他结构中的第一个定义是否具有零偏移量?

时间:2013-10-10 13:55:39

标签: c struct

我们有以下结构:

struct parent {
    char *name;
};

struct child {
    struct parent parent;
    int other_child_specific_data;
};

我们还有与struct parent一起使用的功能:

void print_parent_name(struct parent *p)
{
    printf("%s\n", p->name);
}

问题:我可以肯定,调用这个函数是这样的:

struct child c;
c.parent.name = "Child #1";

print_parent_name(&c);

始终

相同
print_parent_name(&c + offsetof(struct child, parent));

换句话说,问题是:offsetof(struct child, parent) 始终等于零,如果struct parent parent被定位为{{>第一定义struct child 1}}?

可能有人可以给C标准参考吗?是否有这样的硬件或软件配置使这些结构中的offsetof(struct child, parent)不等于零?

2 个答案:

答案 0 :(得分:5)

是的,C(或C ++中的结构的第一个元素的偏移量,受某些类C条件限制)保证为零。

供参考,请参阅https://stackoverflow.com/a/10958596/4323中引用的C99标准:

  

在结构对象中,非位域成员和单位   哪些位字段的地址会按顺序增加   他们被宣布。适当地指向结构对象的指针   转换后,指向其初始成员(或者如果该成员是   bit-fi eld,然后到它所在的单位),反之亦然。那里   可能是结构对象中的未命名填充,但不是在其中   开始。

答案 1 :(得分:3)

是的,你可以肯定。结构总是按其成员定义的顺序设置,并且对齐不能使零偏移之外的非零偏移。

然而,你的行

print_parent_name(&c + offsetof(struct child, parent));

将不会执行您想要的操作,因为&c是指向结构的指针,并且您调用指针算术,将偏移量与结构的大小相乘。当然,如果偏移量为零,这没有效果,但如果我是你,我会用这个:

print_parent_name(&c.parent);

这具有避免指针转换的良好效果。