Hacker News new | ask | show | jobs
by MuffinFlavored 465 days ago
how similar are the C abstractions in ffmpeg and qemu given they were started by the same person?
2 comments

I haven’t worked with ffmpeg’s code, but I have worked with QEMU. QEMU has a lot of OOP (implemented in C obviously) that is supported by macros and GCC extensions. I definitely think it would have been better (and the code would be easier to work with) to use C++ rather than roll your own object model in C, but QEMU is quite old so it’s somewhat understandable. I say that as someone who mostly writes C and generally doesn’t like using C++.
What's the reason for ffmpeg to use C, also historic?
Fabrice also wrote the Tiny C compiler, so very much his language of choice ..

For those used to the language it was seen as "lighter" and easier to add OO like abstractions to your C usage than bog down in the weight and inconsistencies of (early) C++

https://bellard.org/

https://en.wikipedia.org/wiki/Fabrice_Bellard

> 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 issues with C and C++ that it just makes sense to use. An example from a codebase I spend a lot of time in is

    int val;
    bool valueSet = getFoo(&val);
    if (valueSet) {}
    printf(“%d”, val); // oops
The bug can be avoided entirely with C++

    if (int val; getFoo(&val)) // if you control getFoo this could be a reference which makes the null check in getFoo a compile time check
    {}
    printf(“%d”, val); // this doesn’t compile.
For C users. And C++ users:

In C++ we can declare variable in the while or if statement:

https://en.cppreference.com/w/cpp/language/while

https://en.cppreference.com/w/cpp/language/if

It's value is the value of the decision. This is not possible with C [1].

Since C++17 the if condition can contain an initializer: Ctrl+F if statements with initializer

https://en.cppreference.com/w/cpp/language/if

Which sounds like the same? Now you can declare a variable and it value is not directly evaluated, you also can compare it in a condition. I think both are neat features of C++, without adding complexity.

[1] Also not possible with Java.

You could write this in C, no?

  { int val; if (getFoo(&val)) {
    ...
  }}
Both ways of expressing this are weird, but stating that this can't be achieved with C is dishonest in my opinion.
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.
This will be in C2Y and is already supported by GCC 15: https://godbolt.org/z/szb5bovxq
C has less moving parts — it’s more difficult to define a subset of C++ that actually works across all platforms featuring a C++ compiler, not to mention of all the binary-incompatible versions of the C++ standard library that tend to exist — and C is supported on a wider variety of platforms. If you want to maximize portability, C is the way to go, and you run into much fewer problems.
Much easier to link / load into other language binaries surely.
extern “C” works just fine.
Only in certain limited cases, for example, can't have static class instances or anything else that could require calling before a call from "extern C" API.

Also now you have to build enough of a C API to expose the features, extra annoying when you want the API to be fast so it better not involve extra level of indirections through marshalling (hello, KDE SMOKE)

At some point you're either dealing with limited non-C++ API, or you might find yourself doing a lot of the work twice.

Only if your entire API doesn't contain any C++.
C is also C++, at least the C89 subset.
QEMU's abstractions were added when Fabrice was almost completely inactive already (starting in 2008 for some command line support).