Live data from Hacker News

Exploring Polymorphism in C: Lessons from Linux and FFmpeg's Code Design (2019)

leandromoreira.com

71–80 of 131 posts

Re: Exploring Polymorphism in C: Lessons from Linux and FFmpeg's Code Design (2019)

#72

Earlier quoted context omitted.

interfaces in Go are structural. Interfaces in Java are nominal and require immediate declaration of intent to implement at type definition.

Shouldn’t this be named phenomenal rather than structural ? In both cases there is a structure assumed, but one is implicitly inferred while the other one is explicitly required.

The difference is that in Go, an interface is assumed to match if the method signatures match. In other words, the match is done on the type structure of the interface, hence the “structural” designation. Nominal typing, on the other hand, considers that interfaces tend to be associated with important semantic requirements in addition to the type signature, and that mere type-structure matching doesn’t at all guarantee a semantic match. For that reason, the semantics are implicitly bound to the declared name of the interface, and the way for an implementation to claim conformance to those semantics is to explicitly bind itself to that name.

Re: Exploring Polymorphism in C: Lessons from Linux and FFmpeg's Code Design (2019)

#73
post #50

For the record, this design pattern is called a virtual method table, or vtable. I'm surprised that this article never mentioned the term. C++ programmers will know this pattern from the `virtual` keyword.

I've noticed many large C projects resort to these sorts of OOP-like patterns to manage the complexity of the design and size of the code base. But I'm not aware of any one standard way of doing this in C. It seems C++ standardized a lot of these concepts, or C++ developers adopted standard patterns somehow.

> I've noticed many large C projects resort to these sorts of OOP-like patterns to manage the complexity of the design and size of the code base

The Power of Interoperability: Why Objects Are Inevitable

https://www.cs.cmu.edu/~aldrich/papers/objects-essay.pdf

Re: Exploring Polymorphism in C: Lessons from Linux and FFmpeg's Code Design (2019)

#74
post #67
post #60

Earlier quoted context omitted.

> For example, every example in Kernighan & Ritchie: "The C Programming Language (2nd Edition)" is also a C++ program. " That is rather dated, they do things like explicitly cast the void* pointer returned by malloc, but point out in the appendix that ANSI C dropped the cast requirement for pointer conversions involving void , C++ does not allow implicit void conversions to this day.

> Well written C tends to be legal C++ also The "well written" remark is relevant. Many style guides will consider implicit void conversions not well written C. Naturally we are now on C23, and almost every C developer considers language extensions as being C, so whatever.

[deleted]

Re: Exploring Polymorphism in C: Lessons from Linux and FFmpeg's Code Design (2019)

#75

Earlier quoted context omitted.

and C++ also supports optimizing them, especially when you use `final` keyword and LTO which is able to devirtualize at the scale of a whole program.

Interesting, in Rust those optimizations are more implicit since there's no "final" keyword when you use dynamic dispatch via trait objects. + you also got LTO. I wonder if there are many cases where C++ will devirtualize and Rust won't. But then again Rust devs are more likely to use static dispatch via generics if performance is critical.

> But then again Rust devs are more likely to use static dispatch via generics if performance is critical.

Put another way, in C++ the dynamic dispatch is implicit, so you might write code which (read literally) has dynamic dispatch but the optimizer will devirtualize it. However in Rust dynamic dispatch is explicit, so, you just would not write the dynamic dispatch - it's not really relevant whether an optimizer would "fix" that if you went out of your way to get it wrong. It's an idiomatic difference I'd say.

Re: Exploring Polymorphism in C: Lessons from Linux and FFmpeg's Code Design (2019)

#76
post #35

Earlier quoted context omitted.

> weight and inconsistencies of (early) C++ Since very little is ever removed from C++, all the inconsistencies in C++ are still there.

Every language has inconsistencies, and C is not stranger to that. Much of c++’s baggage is due to C and you carry the same weight. That’s not to say that initialization isn’t broken in C++, but just like many features in many languages (off the top of my head in C - strcpy, sprintf, ctime are like hand grenades with the pin pre pulled for you) don’t use them. There’s a subset of C++17 that to me solves so many issue…

Variables like "valueSet" scream out that the language lacks a Maybe type instead. One of the worst things about C++ is that it's content to basically not bother improving on the C type system.

Re: Exploring Polymorphism in C: Lessons from Linux and FFmpeg's Code Design (2019)

#77
post #13

I'd say at 20kloc of C, https://www.lua.org/ gets you as far up the Object Oriented tower as you want.

The article is about using OO techniques directly in C code. Lua is implemented in C but it's an entirely separate language. Does its implementation use OO techniques as part of its C source code? If not, then it's not really relevant.

I don't see how a distinction here is anything but semantically arbitrary.

Transitively, it most definitely uses OO techniques. Furthermore, by having such a clean C ffi (in both directions) it allows for the weaving of the Lua based OO techniques back into C code.

Re: Exploring Polymorphism in C: Lessons from Linux and FFmpeg's Code Design (2019)

#78
post #67
post #60

Earlier quoted context omitted.

> For example, every example in Kernighan & Ritchie: "The C Programming Language (2nd Edition)" is also a C++ program. " That is rather dated, they do things like explicitly cast the void* pointer returned by malloc, but point out in the appendix that ANSI C dropped the cast requirement for pointer conversions involving void , C++ does not allow implicit void conversions to this day.

> Well written C tends to be legal C++ also The "well written" remark is relevant. Many style guides will consider implicit void conversions not well written C. Naturally we are now on C23, and almost every C developer considers language extensions as being C, so whatever.

Well written idiomatic C is certainly not valid C++.

Re: Exploring Polymorphism in C: Lessons from Linux and FFmpeg's Code Design (2019)

#79

Earlier quoted context omitted.

It’s not satire, it’s how you do full OO in plain C.

It's overloaded - it is satire, but also, it isn't.

Exactly. Thank you for your time, I will and won't be here all week!

Re: Exploring Polymorphism in C: Lessons from Linux and FFmpeg's Code Design (2019)

#80
post #27

Earlier quoted context omitted.

You can take it a step further: - instead of setting the same function pointers on structs over and over again, point to a shared (singleton) struct named "vtable" which keeps track of all function pointers for this "type" of structs - create a factory function that allocates memory for the struct, initializes fields ("vtable" included), let's call it a "constructor" - make sure all function signatures in the shared…

> You can take it a step further: No, that is essentially what Linux does in this article (and by the looks of it also ffmpeg). struct file does not have a bunch of pointers to functions, it has a pointer to a struct file_operations, and that is set to a (usually / always?) const global struct defined by a filesystem. As you can see, the function types of the pointers in that file_operations struct take a struct file…

The proto-C++ transpiler used C with this and similar techniques behind the scenes: https://en.wikipedia.org/wiki/Cfront
Post reply on HN