694733, , , , ( )
struct Base{
int x;
}
struct Derived{
int y;
struct Base b;
}
struct Derived d = {0}, *pd = &d;
void getx (struct Base* b);
, , ,
getx (&d.b);
getx(&pd->b).
. , NULL, , & pd- > b
(struct Base*)((char*)pd + offsetof(struct Derived, b))
so & ((Derived *) NULL) → b
((struct Base*)offsetof(struct Derived, b)) != NULL.
IMO - , C , plan9,
struct Derived{
int y;
struct Base;
} d;
getx (& d), Derived , , getx (& d.b) . , , . , , (== inheriting) , NULL . , ,
struct TwiceDerived{
struct Derived;
int z;
} td;
getx (& td). , getx, d.x( td.x pd- > x).
, gcc, downcasting (.. )
#define TO(T,p) \
({ \
typeof(p) nil = (T*)0; \
(T*)((char*)p - ((char*)nil - (char*)0)); \
}) \
-
struct Base b = {0}, *pb = &b;
struct Derived* pd = TO(struct Derived, pb);
which is useful if you are trying to perform virtual functions with function pointers.
In gcc you can use / experiment with 9 planned extensions with the extension -fplan9-extensions. Unfortunately, it does not seem to have been implemented on clang.