我们有以下结构:
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)
不等于零?
答案 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);
这具有避免指针转换的良好效果。