home blog reviews contact

2020-05-22

Why I Hate C++

C++ is a horrible language. It's made more horrible by the fact that a lot of substandard programmers use it, to the point where it's much much easier to generate total and utter crap with it. Quite frankly, even if the choice of C were to do *nothing* but keep the C++ programmers out, that in itself would be a huge reason to use C.
— Linus Torvalds, on C++

While the above quote is clearly hyperbole, I do agree with Mr. Torvalds on one thing: C++ is a horrible language.

I should preface this by saying that I use C++ quite often, and I'm not planning on stopping. I'll defend C++ to the death against those assholes that want to rewrite everything in Rust. And, yes, I'm well aware of the valid historical reasons C++ is such a mess.

And yet, C++ is still awful. Here's why.

C++ is Too Big

First, C++ is really several languages rolled into one. How exactly to split it up depends on who you talk to, but I like to think of C++ as being composed roughly as follows:

And of course, we get another layer of shit on top of it every year to try to fix the problems the last layer of shit caused.

The fact that C++ is so large already makes fixing things difficult for the committee. Any new feature has to be compatible with old features, which limits both the semantics and the syntax. All the good syntax is already taken, and there's so many conflicts between existing features that any additions to C++ cause a dozen new foot-guns.

As a syntax example, consider std::array<int, N> a;. If C++ were being created from scratch, we could have had dedicated syntax for arrays, like many other languages do. Something like int a[N] seems pretty natural to me.

As a much worse example, consider lambdas. One of the examples listed on cppreference.com is this:

auto vglambda = [](auto printer) {
    return [=](auto&&... ts)
    {
        printer(std::forward<decltype(ts)>(ts)...);
        return [=] { printer(ts...); };
    };
};

Seriously? This is supposed to make things easier?

Or user-defined literals. Yes, the obvious choice for syntax here is operator"". What? What the actual fuck?

For a semantics example, I'll just point you to the ccpreference page for initialisation. Go ahead, read through that. That's the type of bullshit you have to deal with to create a variable in C++. Creating a variable should not require memorising pages of bullshit.

Design by Committee

Based on the shit the committee adds, you'd almost feel like they've never actually been assed to write a fucking line of the bullshit that is C++ in their life.

There's Too Many Ways of Doing Everything

Relates to my above points of the language being too big and being designed by committee . Each sub-language has it's own way of doing things, which are fine on their own, except they all have to coexist.

We have NULL and nullptr, pointers and references, classes and structs, templates and constexpr/consteval and the preprocessor, std::array and C-style arrays, std::string and C-style strings, typedef and using, all the fucking casts, all the ways to initialise a variable, auto f() -> int and int f(), static (the "only in this file" meaning) and private and anonymous namespaces, malloc/free and new/delete and all the C++ styles of smart pointers, stdio and iostream, and that's just off the top of my head.

The features I listed above aren't exactly the same, but that's the point. They're really, really close, to the point that any (sane) language wouldn't dare include both.

And yes, before you start crying about not using C features in C++, I know that you should generally prefer the C++ version of a lot of these features, but that kind of proves my point. Why does C++ have features in it that you're supposed to never, ever use? That's just more to remember and more limits on the semantics of C++.

Template Error Messages

I TAed a C++ course while I was in school. One mistake from students would lead to literally hundreds of lines of errors, most of which was only tangentially related to the actual code where the mistake happened.

A large part of that job was interpreting error messages for the students. God.

iostream

The whole thing is awful. So awful I've already written a post about it. I cannot overstate how much I fucking hate iostream.

Compile Times

At my second job, a clean build took almost 40 minutes. This was for 500k LOC. A lot of this is related to templates, header files, and optimisations, and yet, we see languages like Rust and D actually having reasonable compile times. Hmmmmmmmmmmmmmmmm.

All I'll say here is, I don't care if there's valid reasons for C++ compile times, they still fucking suck.

Conclusion

Yup, C++ is awful.

Sadly, it's the best we've got for a lot of use-cases. Try writing a fucking game without C++. (A real one, not some pygame bullshit.)

So I'll keep using C++ I guess...