The typical C99 way to extending stuct is something like
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.
I want to access base elements of struct Derived * obj; directly, for example obj->x and obj->y. C11 provide extended structs, but as explained here we can use this feature only with anonymous definitions. 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. I can cast Derived pointer to Base pointer if need do.
Is this acceptable? Are there any pitfalls?
There are pitfalls.
Consider:
On some implementation it could be that
sizeof(Base) == sizeof(Derived), but: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 expectingBase *, and expect it to work.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), butcends up to a area which is covered by the padding at the end ofBase. Passing pointer of this struct to function which expectsBase*and modifies it, might affect padding bits too (padding has unspecified value), thus possibly corruptingcand maybe even creating trap presentation.