My Tough Love for C++

hamid
9 min readAug 19, 2014

--

A True Story

The Good Ol’ days

Many of my friends who knew me back in college still remember how much of an enthusiast I was for anything and everything C++. I read books about it, learned it, tutored it, advocated it, thought of its designers as role models and had an ultimate dream of becoming one of the authorities on its standardization committee.

C++ Templates: The Complete Guide cover.

My first visit to Barnes and Noble’s as an employed adult was to buy a bunch of C++ most renowned titles, e.g.

I was fascinated by all the intricate details and extended discussions on each and every bit and piece of the language. Even among ourselves as college students, we thought of those who wrote C++ as the real gurus. We were greatly impressed by the complexity of the language, and of complexity in general for some reason. It was certainly one of the primary reasons why very few of us seemed to know about web development, for instance, because the worlds of web development and C++ had very little overlap.

Bjarne Stroustrup, Ph.D. — C++ language author

It wasn't just our dreamy little heads to be honest. I mean, look at the list of companies/products using/written-in C++ that the language author himself maintains on his personal website. It doesn't take much to imagine the effect of seeing such a list on junior Computer Science students. Basically, every single piece of software that mattered seemed to be written in C++.

I remember some of my friends who kept struggling with the software development job market in Egypt — which was one of very few things that stood against our C++-enchanted dogma — for years after our graduation just because they wanted to have jobs in which they predominantly coded in C++.

And it’s not that they were seeking to build an expertise in domains where coding in C++ was commonplace, e.g. embedded development, systems programming … etc. In fact, they were building day-to-day business applications that might as well be written in any other mainstream programming language. It was probably a matter of convenience to their companies to keep hiring C++ developers since they all tended to maintain large codebases of legacy libraries they have accumulated over the years. However, in our minds, writing C++ was obviously a virtue in and of itself.

The insatiable beast of details

I almost never stopped reading about C++ or trying to acquire more knowledge about it. But as time went by, I started to feel I was getting too old to keep chasing the endless minute details. I started to appreciate simplicity way more than I used to. I started to appreciate not having to worry about each and every detail. I started to observe how much time it took me to reason about any given snippet of code before getting to actually write it. And it came to my attention that when I write C++, I tend to think too much before writing any code at all because there are often a hundred different issues to consider first, and because — almost — nothing is done on your behalf. Simply put, the details were endless and the net effect was paralyzing.

Do you know what the compiler does when you don’t provide a constructor? or assignment operator? Do you know what to expect if your type does not have a default constructor? Have you considered sealing your class so that it is not inheritable? Or maybe you’d rather mark its destructor as virtual so that destruction is dispatched correctly in case someone decides to use objects of your class and its descendants in a polymorphic context.

Should we use auto_ptr at all (deprecated in C++11 and frowned upon ever before)? Why isn't there an auto_array? Maybe we can use auto_ptr with STL’s vector. Oops! Watch out! There are some caveats you should know about when it comes to using auto pointers with STL containers/algorithms.

Have you considered exception safety? Oh, are you going to use exceptions to start with? How about packaging your modules? Do you think you will need to throw exceptions across DLL boundaries? Will you be exposing functions whose signatures include STL containers or iterators from a DLL? Is it possible to forward declare std::string or std::vector?

Oh, you’re planning to use STL? OK. Did you learn about the caveats of using vectors with booleans? Did you know about C++’s most vexing parse? Are you planning to use iostreams? They’re evil and slow by the way. Use plain old C’s stdlib’s printf instead. They’re much faster and easier to read. Oh, wait! Those are evil, too, since they’re not type-safe and there’s a million ways things could go wrong when you use them.

And then there are the issues originating from the lack of modern facilities that seem to exist otherwise in every standard library out there. Think of the moment you find out that you need, say, regular expressions (added to the standard in C++11) or maybe some XML parsing utilities or maybe Unicode support, only to find out that what you’re looking for is either not straightforward to accomplish or non-existent in the standard libraries to start with.

And with the advent of C++11, the myriad of details seemed to have reproduced. Have you heard about rvalue references and move semantics? Do we need to provide a move constructor now? Does the compiler generate a default one if we don’t? Did you check out the different ways you can capture values in lambda expressions? How about variadic templates?

You keep trying to catch up on the details until there comes a day where you hold your head and say to yourself: “Boy, I've grown too old for this”.

In my mind, C++ always seemed to be spread over 3 different territories:

  • Object-oriented (encapsulation) facilities (classes, inheritance, runtime polymorphism)
  • STL, generic programming and template meta-programming stuff (containers, algorithms, iterators)
  • Standard library facilities (strings, streams, numerics, exceptions and RTTI)

And right beneath all these lies our old friend: C runtime and standard libraries. To me, it always seemed that C++ grew in the 3 directions rather independently. Trying to mix and match parts across territories has often involved much trouble. Therefore, it is not uncommon to find a good percentage of C++ coding guidelines restricting the use of significant parts of the 3 territories altogether in order to maintain a more coherent and simpler subset of the language. It’s fighting the “feature bloat” as Google C++ coding guidelines call it:

“Another issue this guide addresses is that of C++ feature bloat. C++ is a huge language with many advanced features. In some cases we constrain, or even ban, use of certain features. We do this to keep code simple and to avoid the various common errors and problems that these features can cause. This guide lists these features and explains why their use is restricted.”

I think that learning C++ back in college had several advantages. Most importantly, it gets you to understand how things work under the hood, how you get exactly what you design. You roll your own versions of linked lists, trees or whatever you please and see them in action in front of your own eyes. It is essential to have this level of understanding of the basic foundations of Computer Science.

I could even argue that C may be a better option in such contexts. C is way more minimal, concise and self-consistent than C++. It has way fewer primitives and requires much less time and effort to grasp. A simple comparison between the sizes of K&R’s The C Programming Language (272 pages) and the 4th edition of Stroustrup’s The C++ Programming Language (1300+ pages), or maybe C’s ISO standard (683 pages) and C++’s (1338 pages) tells you there is a significant difference in length between the 2 stories.

However, as a mainstream industry programming language, I think C++ is growing beyond control. I don’t think I even know how many years it should take someone to become expert in C++. There has always been a need for a statically-typed, compiled, close-to-metal programming language that offers modern abstractions. I pay close attention to any serious attempts to create alternatives, e.g. Google Go, Mozilla’s Rust, Alexandrescu’s D, even if they’re at their infancy levels, because I believe we shouldn't spend our lives feeding the insatiable beast of details.

Here comes rescue!

C++ boost library logo

But until we land our next close-to-metal programming language, we must not forget that C++ continues to be today’s de-facto standard programming language for native software development. The good news is: we have Boost for the rescue! Boost is a a beautiful set of open source, peer reviewed, cross-platform and high quality C++ libraries that work well with C++ standard libraries and are intended to provide the most commonly needed facilities, all under a very permissive license that encourages both commercial and non-commercial uses.

It even attempts to provide syntactic improvements and simplifications to the core language by employing all the C++ wizardry and trickery you could never imagine possible. For instance, long before C++11 range-based for loops were proposed, Boost has introduced a BOOST_FOREACH macro that would just enable universal iteration on any sequence, be it a plan old array, an STL container or an std::string, you name it!

And in case you’re sick and tired of the endless debates on iostreams vs. cstdlib, you might want to check out Boost.Format. I am pretty sure you’ll be impressed.

If you love the concept of iterators and how it abstracts the relationship between containers and algorithms, check out Boost’s extension of iterator types and categories in the Boost.Iterator Library.

And before you leave, just make sure to check out the index of libraries Boost encompasses. You’re very likely to come shopping real soon.

How I feel about it now

  1. C++ is a key programming language in today’s world of technology.
  2. There is no way any serious systems programmer shouldn't always attempt to stay on top of C++ matters.
  3. I think C++ is getting fiercely unwieldy. And as much as I admire expert C++ developers who go almost as far as practicing sorcery to give us beautiful creations like Boost, I cannot help but sympathize with Alexander Stepanov when he says:

“I consider ugly hacking to be a technical term that describes techniques that use machinery designed for some other purpose to provide fragile partial solutions of fundamental problems. Ugly hacking is invariably “clever”. It is similar to playing the violin with one’s feet. It is admirable that it can be done but its place is in the circus and not in the Conservatoire.”

or when he finally concludes:

“Unfortunately, I will have to use ugly hacking to do certain things. It will allow me to introduce some essential ideas. But please remember that it is an act of desperation. Do not do it yourself unless absolutely necessary. And if you do, do not be proud of your accomplishments but be sad that you had to inflict such ugliness on future readers of your
code.”

(Source: Alexander Stepanov’s notes on programming).

4. I am full of hope that we can do better. My eyes are wide open and I am completely ready to become an early adopter.

I would be happy to hear your stories about your experience with C++, too. Please, share them with me through comments or posts. Thanks for reading.

--

--