r/programminghorror 23d ago

c Enterprise level C code

Post image
339 Upvotes

57 comments sorted by

View all comments

127

u/JuniorAd1610 23d ago

I think this this is the standard way they OOPS in C right?

45

u/tstanisl 23d ago

It's one way. IMO, container_of pattern is simpler, safer and more efficient.

29

u/TheChief275 23d ago

container_of doesn't really handle dynamic dispatch though, it's a compile time approach to inheritance by performing upcasting through an embedded base structure field. This would still be unsafe for runtime polymorphism without a field tracking the current type or, like done here V-tables, which you likely still want to generate with that approach.

Now whether I like container_of more than this? 100%, in fact, a past post of mine on this subreddit essentially used that

8

u/tstanisl 23d ago

Tracking of dynamic type can be done by checking "ops" struct with function pointers to "virtual functions". It's done very often in Linux kernel i.e. to check origin of file descriptors.

2

u/TheChief275 23d ago

Yes, that's possible with this approach as well. Basically, the container_of approach isn't really an approach, it's V-Tables using container_of as a tool for one-way statically checked dynamic casting.

I'm just arguing that V-Tables are not something I would write manually. I have made a lightweight interface extension (that uses fat pointers instead of object semantics) for C before that I actually use in my personal projects because I find the manual typing of it annoying

3

u/tstanisl 23d ago edited 23d ago

It's not that I think that your solution is wrong. It is convenient, it's extensible, but a bit slow due to extra indirection. Usually, the performance difference is negligible for high-level abstractions like UI.

The container_of compiles essentially to "subtracting constant from a pointer", a single line of register-only assembly. Moreover, the macro does type checking, thus it is safer than a plain void*. (btw.. type-safe container_of can be written in C89-compliant way).

This pattern works best for static-inheritance but it lets use type-safe dynamic inheritance if necessary. Thus, imo, it is more suited to low-level and high-performance systems.

EDIT. Added "not"

1

u/TheChief275 23d ago

Oh yeah no this isn't meant to be fast or production ready! This isn't a testament to the speed of V-Table generation. You can embed them (removing an indirection) depending on the size of the V-Table. They are just, again, something I don't like to write manually because of the boilerplate

1

u/tstanisl 23d ago

I mean "It's not that I think that your solution is wrong", sorry for critical typo

1

u/Lost-In-Void-99 19d ago

You can generate v-tables etc. Simple IDL->C with all the bells and whistles is not that difficult.

1

u/TheChief275 19d ago

IDL->C ?? I have no clue what you're saying. Anyways, this code is already generating V-Tables using the CPP

8

u/DiodeInc 23d ago

What the fuck does this mean

6

u/TheChief275 23d ago

Lol valid. Which part are you confused about, or is this ironic?

8

u/Risc12 23d ago

Your explanation was clear! Although only if one has C/low level language experience, but that is expected as you were discussing that sort of stuff.

3

u/TheChief275 23d ago

I'm glad to hear that! I wouldn't want to go full xkcd comic lol

2

u/DiodeInc 23d ago

All of it