[英]Using macro in C11 anonymous struct definition
The typical C99 way to extending stuct is something like 典型的C99扩展结构的方式就像
struct Base {
int x;
/* ... */
};
struct Derived {
struct Base base_part;
int y;
/* ... */
};
Then we may cast instance of struct Derived *
to struct Base *
and then access x
. 然后我们可以将
struct Derived *
实例转换为struct Base *
然后访问x
。
I want to access base elements of struct Derived * obj;
我想访问
struct Derived * obj;
基本元素struct Derived * obj;
directly, for example obj->x and obj->y. 直接,例如obj-> x和obj-> y。 C11 provide extended structs, but as explained here we can use this feature only with anonymous definitions.
C11提供了扩展的结构,但正如这里所解释的,我们只能将此功能用于匿名定义。 Then how about to write
然后怎么写
#define BASE_BODY { \
int x; \
}
struct Base BASE_BODY;
struct Derived {
struct BASE_BODY;
int y;
};
Then I may access Base members same as it's part of Derived without any casts or intermediate members. 然后,我可以访问Base成员,因为它是Derived的一部分而没有任何演员或中间成员。 I can cast Derived pointer to Base pointer if need do.
如果需要,我可以将Derived指针强制转换为Base指针。
Is this acceptable? 这可以接受吗? Are there any pitfalls?
有任何陷阱吗?
There are pitfalls. 有陷阱。
Consider: 考虑:
#define BASE_BODY { \
double a; \
short b; \
}
struct Base BASE_BODY;
struct Derived {
struct BASE_BODY;
short c;
};
On some implementation it could be that sizeof(Base) == sizeof(Derived)
, but: 在某些实现中,它可能是
sizeof(Base) == sizeof(Derived)
,但是:
struct Base {
double a;
// Padding here
short b;
}
struct Derived {
double a;
short b;
short c;
};
There is no guarantee that at the beginning of the struct memory layout is the same. 无法保证结构内存布局的开头是相同的。 Therefore you cannot pass this kind of
Derived *
to function expecting Base *
, and expect it to work. 因此,您无法将此类
Derived *
传递给期望Base *
函数,并期望它能够正常工作。
And even if padding would not mess up the layout, there is a still potential problem with trap presenstation: 即使填充不会弄乱布局,陷阱预置仍然存在潜在问题:
If again sizeof(Base) == sizeof(Derived)
, but c
ends up to a area which is covered by the padding at the end of Base
. 如果
sizeof(Base) == sizeof(Derived)
,则c
结束到Base
末尾的填充所覆盖的区域。 Passing pointer of this struct to function which expects Base*
and modifies it, might affect padding bits too (padding has unspecified value), thus possibly corrupting c
and maybe even creating trap presentation. 将此结构的指针传递给期望
Base*
并修改它的函数,也可能影响填充位(填充具有未指定的值),因此可能破坏c
甚至可能创建陷阱表示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.