Is there a way to make GCC / Clang aware of inheritance in C?

I am writing a C library that uses some simple object oriented inheritance:

struct Base {
    int x;
};

struct Derived {
    struct Base base;
    int y;
};

And now I want to pass Derived * to a function that accepts Base *, something like this:

int getx(struct Base *arg) {
    return arg->x;
};

int main() {
    struct Derived d;
    return getx(&d);
};

This works and, of course, is typical, but the compiler does not know this. Is there any way to tell the compiler that this is a type? I focus only on GCC and clang here, so answers to specific compilers are welcome. I have vague memories of how to see the code that did it with the help __attribute__((inherits(Base))or something like that, but my memory could lie.

+4
source share
3 answers

C, , Base *. , (, , C), C 2011 6.5, 7 :

, lvalue, :

- , ,

...

float, int int float int. (, , undefined.)

, , Derived, Base lvalue. Derived Base C 2011 6.7.2.1 15 :

... , , ...

, Derived Base, , , Derived, , ( ), Derived, Base, .

: , . C 6.5.2.2 2 , , ( , const ), 6.5.16.1 , , ( , ). , Derived , Base, C. , , . , , - .

+5

( ):

getx(&d.base);

void:

int getx(void * arg) {
    struct Base * temp = arg;
    return temp->x;
};

int main() {
    struct Derived d;
    return getx(&d);
};

, C , . , .

+1

694733, , , , ( )

struct Base{
   int x;
}
struct Derived{
   int y;
   struct Base b; /* look mam, not the first field! */
}

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; /* look mam, no fieldname */
} 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.

+1
source

All Articles