在C11匿名结构定义中使用宏
扩展stuct的典型C99方法如下在C11匿名结构定义中使用宏,c,macros,struct,coding-style,c11,C,Macros,Struct,Coding Style,C11,扩展stuct的典型C99方法如下 struct Base { int x; /* ... */ }; struct Derived { struct Base base_part; int y; /* ... */ }; 然后我们可以将struct-Derived*的实例强制转换为struct-Base*,然后访问x 我想访问struct-Derived*obj直接,例如obj->x和obj->y。C11提供扩展结构,但正如前面所解释的,我们只能在匿
struct Base {
int x;
/* ... */
};
struct Derived {
struct Base base_part;
int y;
/* ... */
};
然后我们可以将struct-Derived*
的实例强制转换为struct-Base*
,然后访问x
我想访问struct-Derived*obj代码>直接,例如obj->x和obj->y。C11提供扩展结构,但正如前面所解释的,我们只能在匿名定义中使用此功能。那我们写一篇怎么样
#define BASE_BODY { \
int x; \
}
struct Base BASE_BODY;
struct Derived {
struct BASE_BODY;
int y;
};
然后我可以访问基本成员,就像它是派生的一部分一样,而不需要任何类型转换或中间成员。如果需要,我可以将派生指针转换为基指针
这可以接受吗?有陷阱吗?有陷阱
考虑:
#define BASE_BODY { \
double a; \
short b; \
}
struct Base BASE_BODY;
struct Derived {
struct BASE_BODY;
short c;
};
在某些实现中,可能是sizeof(Base)==sizeof(派生)
,但是:
struct Base {
double a;
// Padding here
short b;
}
struct Derived {
double a;
short b;
short c;
};
无法保证结构的开头内存布局是相同的。因此,您不能将这种派生的*
传递给期望基*
的函数,并期望它工作
即使填充不会弄乱布局,陷阱预安装仍然存在潜在问题:
如果再次sizeof(Base)==sizeof(Derived)
,但是c
结束到Base
末尾的填充所覆盖的区域。将此结构的指针传递给需要Base*
并对其进行修改的函数,也可能会影响填充位(填充具有未指定的值),从而可能损坏c
,甚至可能创建陷阱表示。这是真的。在结构定义和上行的可怕破坏结果之前,我放置了不同的语法包。作为替代,您可以考虑使用<代码> TyPufF(见答案),通过<代码> -FMS扩展< /代码>选项在<代码> GCC < /代码>或<代码> CLAN<代码>中,但它是非标准的。