Live data from Hacker News

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

leandromoreira.com

111–120 of 131 posts

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

#111

Earlier quoted context omitted.

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. I'm not sure I follow - pretty much 99% of usage of C++ in the last, like, 20 years has been around making sure that you get static dispatch with polymorphism through templates. It's exceedingly uncommon to see the `virtual` keyword unless you have, say, some DLL-based run-time plug-in system going on.

yeah true, I'm really liking pornel's reply though on rust objects going between static and dynamic dispatch.

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

#112

> for instance, Linux handles network socket, special files (like /proc/cpuinfo) or even USB devices as files. This is a powerful idea that can make easy to write or use programs for linux since we can rely in a set of well known operations from this abstraction called file. Benno Rice gave a fantastic talk a few years ago called "What UNIX Cost Us," which he starts off by showing how to write some USB device code in…

The same is visible in having to parse a bunch of Linux's more complex of the /proc entries, vs. simply using syscalls in (say) FreeBSD. "Everything is a file" is not a bad abstraction for some things . It feels like Linux went the route of a golden hammer here.

That's the gist of his whole talk – that doing things "the UNIX way" (which can be defined to various degrees of specificity) has been cargo culted, and that we should reexamine whether solutions that were pragmatic 50+ years ago is still the best we can do.

The specific reason I mentioned it was because his initial example was about how much more ceremony and boilerplate is needed when you need to pretend that USB interfaces are actually magic files and directories.

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

#113
post #102

Earlier quoted context omitted.

GNU C++ once had this feature; it was called Signatures. It was removed, though. A signature declaration resembled an abstract base class. The target class did not have to inherit the signature: just have functions with matching names and types. The user of the class could cast a pointer to an instance of the class to a pointer to a compatible signature. Code not knowing anything about the class could indirectly call…

Nowadays you can do that with concepts.

I don't see how concepts can emulate signatures to the full extent that the target object can be manipulated as if it conformed to an abstract base, without any wrapper object being required to handle it.

Without signatures, we have to use some kind of delegating shim which takes the virtual function calls, and calls the real object. It could be a smart pointer.

With signatures, we don't use smart pointers, just "pointer to signature" pointers. However, I suspect those pointers had to be fat! Because, surely, to delegate the signature function calls to the correct functions in the target object class, we need some vtable-like entity. The signatures feature must generate such a vtable-like table for every combination of signature and target class. But target object has no space reserved in it for that table pointer. The obvious solution is a two-word pointer which holds a pointer to the object, and a pointer to the signature dispatch table specific to the signature type and target object's class.

If we can use concepts to do this, with a smart pointer that ends up being two words (e.g. pointer to its own vtable, and a pointer to the target object), we have broken even in that regard.

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

#114
post #91

Earlier quoted context omitted.

For one, ffmpeg is 9 years older than Go. Plus, when dealing with video files a garbage collected language probably isn't going to cut it. C++ and Obj-C also feel overkill for ffmpeg.

Apparently someone has not read the article, otherwise you would have had understood my point about Go. Secondly, Apple and Microsoft, do just fine with Objective-C and C++ for their video codecs, without having to manually implement OOP in C.

CoreVideo and CoreAudio are both implemented in C on Apple systems. There are higher level APIs like AVFoundation implemented in Obj-C/Swift, but the codecs themselves are written in C. Even the mid-level frameworks like AudioToolbox and VideoToolbox are written in C. I’m not as familiar with Microsoft but imagine it’s similar.

Also the article doesn’t actually mention OOP. You can use polymorphism without fully buying into OOP (like Go does).

The great thing about C is its interoperability, which is why it’s the go to language for things like codecs, device drivers, kernel modules, etc.

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

#115
post #97
post #93

Earlier quoted context omitted.

No, declaring a variable in a `for` loop is supported in C99 but you can't do if-init.

Ah, you're right (finally tried it out). But it 100% works in a loop (usually for loop)

It’s one of those things that I never knew I wanted until I started using it, and now i miss it when it’s not available.The reason you want it is the same reason you want to declare a variable in the statement of a for loop rather than pre declaring and using a while loop

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

#116
post #102

Earlier quoted context omitted.

Nowadays you can do that with concepts.

I don't see how concepts can emulate signatures to the full extent that the target object can be manipulated as if it conformed to an abstract base, without any wrapper object being required to handle it. Without signatures, we have to use some kind of delegating shim which takes the virtual function calls, and calls the real object. It could be a smart pointer. With signatures, we don't use smart pointers, just "poi…

Here is an example then, assuming you mean this kind of abstrations,

    #include 

    using namespace std;

    template 
    concept Speaker = requires (T t) {
        t.speak();
    };

    class Duck {
        public:
        void speak() const {
            cout 
    void speaking_animal(const T&  animal) {
        animal.speak();
        cout 
    void speaking_farm(const T&... animals) {
        auto space_adder = [&](auto creature) -> void {
            creature.speak();
            cout 
Live example, https://godbolt.org/z/vPhf13xEh

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

#117
post #101
post #43

Earlier quoted context omitted.

It's how you do it in many C++ implementations, but IIRC it's not actually mandated in any way unless you strive for GCC's IA-64 ABI compatibility (the effective standard on Linux for C++) C++'s vtables are also, in my experience, especially bad compared to Objective-C or COM ones (MSVC btw generates vtables specifically aligned for use with COM, IIRC). Mind you it's been 15 years since I touched that part of crazy.

It is more the other way around, COM was designed to fit with how MSVC generates vtables. It is a simplification of OLE, and by the time the idea came up to use that approach, there were tons of OLE code since Windows 3.1. By the way it wasn't gone away, after how Longhorn went down, it became the main API delivery mechanism on Windows, sadly improving the tooling has never been a pritority other than half-finished a…

IIRC the rule now is that every new API has to be provided through a COM interface

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

#118
post #97

Earlier quoted context omitted.

Ah, you're right (finally tried it out). But it 100% works in a loop (usually for loop)

It’s one of those things that I never knew I wanted until I started using it, and now i miss it when it’s not available.The reason you want it is the same reason you want to declare a variable in the statement of a for loop rather than pre declaring and using a while loop

I've used it in go a lot. If you want to kludge it, you can still put a block around the if. But it's not nearly as nice

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

#119
post #91

Earlier quoted context omitted.

Apparently someone has not read the article, otherwise you would have had understood my point about Go. Secondly, Apple and Microsoft, do just fine with Objective-C and C++ for their video codecs, without having to manually implement OOP in C.

CoreVideo and CoreAudio are both implemented in C on Apple systems. There are higher level APIs like AVFoundation implemented in Obj-C/Swift, but the codecs themselves are written in C. Even the mid-level frameworks like AudioToolbox and VideoToolbox are written in C. I’m not as familiar with Microsoft but imagine it’s similar. Also the article doesn’t actually mention OOP. You can use polymorphism without fully buyi…

I bet they are actually C++ with extern "C" public APIs.

Additionally Metal is implemented in Objective-C, with Swift and C++ bindings.

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

#120
post #117
post #101

Earlier quoted context omitted.

It is more the other way around, COM was designed to fit with how MSVC generates vtables. It is a simplification of OLE, and by the time the idea came up to use that approach, there were tons of OLE code since Windows 3.1. By the way it wasn't gone away, after how Longhorn went down, it became the main API delivery mechanism on Windows, sadly improving the tooling has never been a pritority other than half-finished a…

IIRC the rule now is that every new API has to be provided through a COM interface

That rule has been like that since Vista came to be, when .NET approach from Longhorn was redone in COM/C++.
Post reply on HN