3

我们有以下结构:

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?

可能有人可以参考C标准吗?是否存在使offsetof(struct child, parent)此类结构不等于零的硬件或软件配置?

4

2 回答 2

5

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

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

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

于 2013-10-10T14:02:57.067 回答
3

是的,你可以确定。结构始终按照定义其成员的顺序设置,并且对齐不能从零偏移中产生非零偏移。

但是,您的线路

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

不会做你想做的,因为&c是指向你的结构的指针,你调用指针算术,将偏移量乘以结构的大小。当然,如果偏移量为零,这将无效,但如果我是你,我会使用这个:

print_parent_name(&c.parent);

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

于 2013-10-10T14:05:50.317 回答