我正在C89中实现一棵二叉树,并且试图通过组合在所有节点结构之间共享公共属性。因此,我有以下代码:
enum foo_type
{
FOO_TYPE_A,
FOO_TYPE_B
};
struct foo {
enum foo_type type;
};
struct foo_type_a {
struct foo base;
struct foo * ptr;
};
struct foo_type_b {
struct foo base;
char * text;
};
我在所有结构定义中都包含类型struct foo
的成员作为其初始成员,以便提供对enum foo_type
所拥有的值的访问,而与结构类型无关。为此,我期望指向结构对象的指针指向其初始成员,但是我不确定在这种情况下该假设是否成立。对于C99,该标准规定以下内容(请参阅ISO / IEC 9899:1999 6.7.2.1§13)
指向经过适当转换的结构对象的指针指向其初始成员(或者,如果该成员是位字段,则指向它所驻留的单元),反之亦然。结构对象中可能有未命名的填充,但在其开头没有。
尽管所有结构作为其初始成员都共享一个公共struct foo
对象,但是填充还是起作用了。虽然struct foo
仅具有一个大小为int
的成员,但是struct foo_type_a
和struct foo_type_b
都包含指针成员,这在某些情况下会增加对齐方式,从而增加填充。 / p>
因此,考虑到这种情况,C编程语言(C89或任何后续版本)是否确保通过指向对象的指针访问struct foo::type
的值是安全的,无论该对象的类型为{{ 1}}还是包含类型struct foo
的对象作为其第一成员,例如struct foo
或struct foo_type_a
?
答案 0 :(得分:1)
您自己引用C标准时,C99和更高版本支持您所描述的内容。
似乎C89还支持它,因为您引用的语言早在1988年的ANSI-C文档中就已经存在:
3.5.2.1结构和联合说明符
...
在结构对象中,非位字段成员和单位 位域所在的地址按顺序增加 在其中声明它们。适当地指向结构对象的指针 强制转换,指向其初始成员(如果该成员是位域, 然后转到其所在的单元),反之亦然。也许有 因此是结构对象中的未命名孔,而不是结构对象中的未命名孔 开始,以实现适当的对齐。