In the first post of this series of ramblings (er… history lessons from my point of view) I made the statement that “C++ used to be viewed as the cool kids’ language – now it’s what the old guys make the cool kids use as a form of punishment”.
I was only partly joking. C++ seems to be sort of ‘out of fashion’, especially in the apps world. It cops a lot of criticism for things like templates and macros… lack of garbage-collection and so on. You kids go on about it a lot. When you have to use it, a lot of you whinge (although some don’t). So I want to look at what those objections seem to be (mainly).
But first some history… ‘cuz that’s what I do…
Back in the mid-90s, C++ was what Java seems to be today – the default ’go to’ language (and no, I’m not talking about the command – bite your tongue) for applications. Its potential for improved OS and systems programming over C was well-understood, but OO had everyone’s imagination in overdrive. You could use C++ for anything (it seemed).
We were also just getting used to ideas like templates and exceptions. In the early 90s, it would still be a while before they found their way into the standard, and even longer before they were implemented properly in a most compilers, but just reading about them (in paper magazines, remember those?) made us feel like minor deities. We were getting some serious power.
Templates took abstraction to the next level, and exceptions cleaned up endless layers of error-signalling return values. Probably the biggest reason these were cool was that code-bases were getting bigger and more complex. We needed new ways of handling that, and these things were an attempt to do that.
But it wasn’t complexity-reduction that captured my imagination back then. I enjoy software for its own sake. It’s art, and I like being able to do cool things. C++ was letting me do that. Templates, exceptions, operator overloading, the STL, and ‘all the things’ were very cool toys. Could they get me into trouble? Yes, of course… Could they be misused? Sure. So can a power-drill.
And in C++, I still had all the low-level advantages of C. I could still do pointer arithmetic, cast things any way I liked, throw function pointers around and do all sorts of naughty, primitive things. It was like seeing down into the assembler code. Was it dangerous? You betcha. So’s a scalpel. Would I use these things all the time? Of course not.
But I’ll use anything in my toolkit when I have to. And I have to make sure I know the right time to use a tool, otherwise, I’m better off not using those things. The Great Bjarne famously said that “C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.”
It’s a key point. You have to know what you’re doing.
And here’s another one: the criticisms about C++ I hear from people who use ‘more civilised’ languages (you Java and Python people know who you are) are mainly about things that I consider cool. Yes, things like templates can get you into a massive amount of trouble when you use them badly, but parameterised types have saved me untold hours of cutting-and-pasting code, while retaining type-safety.
Besides, Java’s got the equivalent anyway, even if most Java-ites hate them.
Sure, operator overloading caused a few (or many) problems over the years… until you needed to do some serious maths. Then it makes your code all nice and readable. And overloading the bit-shift operators for IO streams is clever and works really well. Being honest, I don’t have any other good examples of why operator overloading is useful, but those two cases are things I’ve used a lot, and still like. I bet there are more.
And OK, macros suck. They have an alien syntax that just interrupts your flow of thought whenever you have to use them. And their potential for long-term damage is massive. But they can also get you out of a lot of trouble and save a lot of typing. Again – a powerful (and possibly rather blunt) tool.
Now here’s a piece of pure opinion from me: C++ is the last of the popular languages to give you advanced programming paradigms, while not attempting to protect you from danger.
It seems to me that every language that purports to be more advanced or sophisticated than C++ wants to wrap me in more and more cotton wool, just in case I do something wrong. They seem desperate to take away all my sharp things (like pointers – sorry, couldn’t resist) in case I hurt myself. It’s as if they don’t trust me to think for myself, or properly learn about what I’m doing.
I’m not saying you don’t get something in return. Garbage collection is a time-saving gift from On High in so many application-level situations… except when you want to know exactly when something is being cleaned up, and do something specific at that point.
And dynamic typing can save a lot of time and hassles with inheritance. It sort of makes templates a bit redundant, too… except when a particular (and necessary) behaviour hasn’t been implemented properly, but you only find that out after your software is released, because it’s only invoked in certain rare cases. You can only ever catch dynamic type problems at runtime.
Of course, this encourages more thorough testing, which is A Good Thing all around, but that’s a hobby-horse for another post.
I suppose that the underlying point is that the differences in newer languages may be pragmatic tradeoffs, but they’re also ‘safety nets’, trying to protect us from ourselves. Whether or not you want that is up to you, but another point is that C++11 includes a lot of these ‘cool new features’ without taking away your power to do the low-level stuff. So you can keep your pointy things, and still use things like lambda functions and proper container iteration.
Powerful things are dangerous. We have to use them carefully. On Stroustrup’s FAQ page in the “Did you really say that?” section (from which I got the ‘blowing your leg off’ quote), he goes on to say this:
What people tend to miss, is that what I said there about C++ is to a varying extent true for all powerful languages. As you protect people from simple dangers, they get themselves into new and less obvious problems. Someone who avoids the simple problems may simply be heading for a not-so-simple one. One problem with very supporting and protective environments is that the hard problems may be discovered too late or be too hard to remedy once discovered. Also, a rare problem is harder to find than a frequent one because you don’t suspect it.
Next post I’m getting stuck into Microsoft again, talking about DLLs and .Net. Can’t wait for that one.