struct packing:如何在开头添加struct成员?

问题描述 投票:1回答:1

我正在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:19996.7.2.1§13)

指向适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。结构对象中可能存在未命名的填充,但不是在其开头。

虽然所有结构共享一个共同的struct foo对象作为其初始成员,但填充起作用。虽然struct foo只有一个像int大小的成员,但struct foo_type_astruct foo_type_b都包含指针成员,这在某些情况下会增加对齐并因此增加填充。

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

c memory-alignment c89 packing
1个回答
1
投票

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

看来它也得到C89的支持,因为你引用的语言已经出现在1988年的ANSI-C文件中:

3.5.2.1结构和联合说明符

...

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

© www.soinside.com 2019 - 2024. All rights reserved.