结构打包:如何在开始时添加结构成员?

时间:2019-04-07 15:02:25

标签: c memory-alignment c89 packing

我正在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_astruct foo_type_b都包含指针成员,这在某些情况下会增加对齐方式,从而增加填充。 / p>

因此,考虑到这种情况,C编程语言(C89或任何后续版本)是否确保通过指向对象的指针访问struct foo::type的值是安全的,无论该对象的类型为{{ 1}}还是包含类型struct foo的对象作为其第一成员,例如struct foostruct foo_type_a

1 个答案:

答案 0 :(得分:1)

您自己引用C标准时,C99和更高版本支持您所描述的内容。

似乎C89还支持它,因为您引用的语言早在1988年的ANSI-C文档中就已经存在:

  

3.5.2.1结构和联合说明符

     

...

     

在结构对象中,非位字段成员和单位   位域所在的地址按顺序增加   在其中声明它们。适当地指向结构对象的指针   强制转换,指向其初始成员(如果该成员是位域,   然后转到其所在的单元),反之亦然。也许有   因此是结构对象中的未命名孔,而不是结构对象中的未命名孔   开始,以实现适当的对齐。