BrT
BrT

Reputation: 629

Inheritance in C: good, bad, or other?

We have a large C code base that has been developed over several decades. One of the features of the code is a large dependence on function pointers and pseudo inheritance. The idiom (as discussed here) follows like so:

typedef struct twod_ {
    double x, y;
} twod;

typedef struct threed_ {
    twod super;
    double z;
} threed;

threed *point_3d;
twod *point_2d = (twod *)point3d;

At which point point_2d->x and point_3d->x are the same block of memory.

My questions are:

Of course, the adage "if it aint broke, don't fix it" would be a good one to keep in mind; however, that isn't really helping us at the moment, so we think we might have to go deeper with refactoring...

Thanks!

Upvotes: 5

Views: 554

Answers (4)

Lundin
Lundin

Reputation: 214300

Is this idiom still popular in modern production code? (Any recommended open source examples)

It is somewhat rare, though you see it now and then. I wouldn't call it popular, the uses of polymorphism in C programs are often few.

This code has a requirement for performance -- does this idiom help with speed and/or memory usage?

It will certainly not make the code more efficient than a struct containing all 3 members. At worst, the heritage will make the code less efficient. The best way to tell is to disassemble to compiler output for your specific platform and see for yourself.

...is this a problem with the implementation, or the idiom?

Inheritance in general should be used carefully, inheritance for the sake of inheriting fills no purpose. That is true for all OO languages.

Personally, I do think this particular idiom and similar attempts to include mildly useful OO features in C are problematic. Mainly because they add significant complexity to the program. Things like this were preached in the book "Object-orientated programming with ANSI-C" (Axel-Tobias Schreiner, released early 90s). I personally find most things in that book quite horrible.

in an ideal world, would 500k LOC with this idiom be quickly understood?

That depends a lot more on the program structure, file structure and coding standards, than on this little OO idiom. Though of course 500k loc will not be quickly understood even if the program is state of the art.

Upvotes: 0

WoLfulus
WoLfulus

Reputation: 1977

This will work, but the problem you have to keep in mind that the compiler will not warn/say anything to you about problems related to variable access or anything like that. This method not type-safe because sometimes this explicit casts can be evil. Take this example as example:

typedef struct _A
{
    double x, y;
} A;

typedef struct _B 
{
    A super;
    double z;
} B;

typedef struct _C 
{
    A super; // we wanted B, but wrote A by mistake
    double w;
} C;

C* c;
B* b = (B*)c;

// will write to C::w instead of B::z and no one will warn you about this.
// you'll need to track this by hand after your application crashes.
b->z = 1234; 

This type of thing can put an airplane on the ground easly. :)

About performance, this will end up doing the same thing as if you take the pointer to super by hand (more safe than casting):

A* a;
B* b = &a->b; 

Also I don't think this is popular these days (at least not for younger programmers like me that grew programming in more modern compilers)

Also, C++ compiler is an option? More modern compilers these days that allows struct inheritance - better than casting it this way.

Upvotes: 1

asaelr
asaelr

Reputation: 5456

Like (almost) everything in C, as long as you know what do you do, it's fine. But be aware that problems can appear very easyly - for example, if you have an array of threed, you can't cast it to an array of twod. (accessing members of that casted array is undefined behavior)

Upvotes: 0

unwind
unwind

Reputation: 399949

I'd say it's fine, although of course it can be easy to go confused since it becomes rather verbose.

For me, the flagship open source implementation of "C with classes" is probably GTK+, specifically the gobject module.

Upvotes: 2

Related Questions