1. It is not possible to add optional member functions (which would be pure virtual functions) to a C++ class base class and then check at runtime if they are unimplemented in the object (at least not without implementing some way to query the object, which is slow). If you say to handle this by having typeid checks at runtime, look at the VFS and then notice that you cannot implement this typeid check in advance, since you cannot add a typeid check for a derived class that did not even exist when you compiled your code. Thus, you still need to use structs of function pointers in C++. Maybe you can use C++ classes for some cases where structs of function pointers are used, but you would giving up the ability to implement optional functions in a sane way.
2. It ignores all of the things in C that are absent from C++. In particular, C++ refuses to support C’s variably modified types and variable length arrays, which are useful language features.
3. It ignores all of the things in C++ that you likely do not want, such as exceptions and RTTI. The requirement to typecast whenever you assign a void pointer to any other pointer is also ridiculous.
Furthermore, less is more. You get faster build times with C because it does not support all of the features C++ has. Just because you can do it in C++ does not mean you should.
I used C++ for one of my first projects for a startup in health care and I really wish I had not. C++ made development a hellish experience as I spent most of it on fighting the compiler to be able to use every C++ language feature I could imagine and not enough on actual issues. It easily doubled development time since I spent most of it on things that only existed because C++ had overcomplicated everything (e.g. reference versus pointer, public versus private, shoehorning OOP into places it did not belong, operator overloading, templates, etcetera). This was during my initial attempt at graduate studies and after ruining a semester because of it (this had been intended to be a part time thing), I parted ways with the company. The C++ daemon went on to be the heart of the company, despite the lingering bugs.
I ended up fixing the remaining issues as a consultant years later, but eventually, I realized that everything would have been better had I not used C++ in the first place. There are times when I fantasize about rewriting it in C. One of these days, I might actually do that for the company for free if only to put an end to a mistake of my youth. Unfortunately, now that I have fixed the daemon, it has the advantage of being a mature, reliable codebase, so it is difficult to justify a rewrite.
That said, despite my complaints about the effect C++ had on development, I did a number of things right when architecting that daemon. The lingering bugs turned out to be trivial and it has scaled with the company for 13 years with no end in sight. When it finally is replaced, the reason will likely be that it did not support HA, rather than some inability to scale. My younger self had refrained from pursuing HA since it seemed infeasible to do within the spare time I had during a single semester.
The difference in build times between identical code compiled with the C language or C++ language is probably negligible. Or at least dwarfed by using a better build system, a faster build machine, and/or some sort of build caching technology.
> Beyond that, there is no compiler flag to stop requiring explicit casts of void pointers before assigning them.
I believe that's true. And there are probably a few other ergonomic differences beyond this one. Has anyone proposed that as a feature flag for Clang and/or GCC? Open source C and C++ compiler devs don't have a lot of free time such that they peruse social media looking for things to do.
No comment on your anecdote other than to say I have heard versions of that story before but with other programs and in basically every other language. Including C.
I'm not saying you're wrong. I think a lot of your points are valid points. About taste. Which is fair and fine, but it's also true that the difference between C and C-style C++ are pretty minor, especially if someone knows how to enforce coding standards with clang-query wired up to CI or something like that.
https://godbolt.org/z/z9M55s3q6
What is particularly nice about that code is that a C compiler will realize that it has a buffer overflow. Adapting it for C++ will cause the C++ compiler to not notice the buffer overflow.
If you are going to be writing C, there is no reason to compile it as C++. Using C++ limits your ability to use newer features of C and exposes you to headaches like the ABI compatibility break of GCC 5.0 that was done for C++11. C has never had an ABI compatibility break caused by a revision of the language. Your suggestion that people should use C++ even when it is not what anyone wants befuddles me.
If you said this in a room with Linus Torvalds, I wonder if he would start cursing again.