Around 20 years ago I found a job as a C++ developer. My new employer provided me the first day with a PDF file defining the very strict and mandatory set of guidelines to be followed for the production of code in the organization. These rules can be summarized as follows: do not use the Standard Template Library; do not use templates; and do not use multiple inheritance. If you are a C++ developer reading the previous phrase, I hope you can understand the dismay I felt while reading that. If you are not a C++ developer, suffice to say that to this day I do not understand why would anyone choose to use C++ without those features.
A programming language is called a “language” for a reason: it contains a set of grammar rules and a dictionary of reserved words, which can be put together in certain ways to produce a particular semantic. No French poet would consciously avoid Alexandrines other than for stylistic purposes, and no Latin poets stayed away from Saturnians when the time came. Those forms are tools, and even if admittedly, human languages are much less mathematical than programming ones, they are all part of a poet’s arsenal, and rightfully so.
I have long meditated about the reasons behind the conscious choice of forbidding certain forms of C++ in this company’s product. I have concluded that it had less to do with the explicit reasons they gave in their guidelines document (readability, maintainability, some other ability) and more with the fact that in 2006 C++ was stuck in a limbo. The standard in vogue at the time, the 2003 edition, which was a bug-correcting revision of the 1999 one, was quickly losing its prominence as an application programming language, replaced by other, more hyped, languages, almost all at a higher level in the abstraction hierarchy, and featuring a proverbial garbage collector: Java, C#, Scala, Erlang, Ruby, and Python.
(It must be said at this point, that the software product in question was a business application written for Windows, whose development had originally started in the mid-1990s, and which used object-oriented programming features extensively to model various business entities.)
We must remember that 2006 was also the year of Bruce Tate’s “Beyond Java”; a time of experimentation and possibilities. JavaScript had all of a sudden “good parts”; Rails was taking everyone by surprise. The OOP Hype Cycle was getting stuck in its trough of disillusionment. Last but not least, it was also the time of “Writing Secure Code” being a mandatory reading at Microsoft, with the public opinion openly blaming C and C++ and their goddamn pointers for pretty much every software security disaster making headlines.
(To make a long story short, my employer chose to move to Java shortly after, for the next version of their flagship application. This was a rewrite that proved costly, not only in financial but also, and painfully enough, in human terms. But that is material for another story.)
Back to the coding guidelines, the explicit choices therein (no multiple inheritance, no STL, no templates) made the codebase unwieldy, heavy, prone to repeated code, and hard to evolve. In particular, avoiding multiple inheritance even prevented the team from using pure abstract classes with virtual methods (akin to Java and C# interfaces, or Objective-C and Swift protocols) which are, by all means, a fantastic abstraction and design mechanism. I could digress for many more pages; in short, and in hindsight, I do consider such choices a sad mistake.
During the year and a half I spent in that company, however, I had the immense chance of discovering the outstanding work of Scott Meyers. To say that his book “Effective C++: 55 Specific Ways to Improve Your Programs and Designs” had a strong effect in me is an understatement. I still own my copy of the second edition (published in 2005), and to this day, even though C++ has evolved in ways that nobody could have predicted back in 2006 (and thankfully so!) it still remains a staple of my library, and the go-to book whenever I have to work on C++ code (which is not that often, alas). Last but not least, this was the book that opened the door to my university degree in 2008.
Scott (I hope he does not mind me calling him by his first name) is one of my all-time heroes in the world of programming. To give you an idea why, I will just quote a 2003 panel where he was asked about how to interview programmers, and his observations are golden:
I hate anything that asks me to design on the spot. That’s asking to demonstrate a skill rarely required on the job in a high-stress environment, where it is difficult for a candidate to accurately prove their abilities. I think it’s fundamentally an unfair thing to request of a candidate.
Yes, Scott. This magazine wholeheartedly agrees with you.
But back to the book. There is one precise reason why I admire (and still consult) “Effective C++” 20 years after its publication; C++ might have changed in the past two decades, yet the tenets that define the spirit of the language (most of which are described in the book) are still the same. I have grown a fondness for boring technology, proven time and again, and backed by a solid ecosystem around it: C++ ticks all of these boxes.
“Effective C++” is, in essence, a book quite similar to Robert L. Glass’ “Facts and Fallacies of Software Engineering”: a series of very specific guidelines, stating clearly what to do (and most importantly, what not to do) in various situations and conundrums. In this case, regarding the essence of C++.
Let us see some examples, starting with Item 1, “View C++ as a federation of languages”:
Today’s C++ is a multiparadigm programming language, one supporting a combination of procedural, object-oriented, functional, generic, and metaprogramming features.
Yes, functional features, too. C++ is a very complex beast, offering unprecedented levels of flexibility and power. Why restrict oneself?
The power of C++ often comes hidden, however, and as Item 5 explains, developers must “Know what functions C++ silently writes and calls”.
When is an empty class not an empty class? When C++ gets through with it. If you don’t declare them yourself, compilers will declare their own versions of a copy constructor, a copy assignment operator, and a destructor.
Developers new to C++ are simply unaware of such rules; they are certainly not obvious at first sight, and can lead them to write code that simply does not behave as expected. In the same vein, Item 7 reminds you of making destructors virtual in polymorphic class families, while Item 9 tells you not to call virtual functions in constructors nor destructors.
Scott dives into the famous RAII principle in the third chapter, starting with Item 13, “Use objects to manage resources”. Then it uses chapters 4 and 6 to explain code design techniques, arguably useful not only for C++ code but in so many other languages. The quintessential example? “Item 22: Declare data members private”. Duh.
Item 31, “Minimize compilation dependencies between files” has the intended effect of speeding up the compilation of C++ projects, a fact often neglected in large codebases. For the anecdote, the system of my employer consisted of half a million lines of code, and took around three hours to compile on a standard single-core PC of 2006, using the current version of the Microsoft C++ compiler. One of my colleagues literally spent a weekend applying Scott’s best practices, and cut down the compilation time… in half.
Finally, Item 53 is a pet peeve of mine: “Pay attention to compiler warnings”. Although to be honest, I would have not only suggested to pay attention to them, but literally to remove them altogether. I also remember applying this principle to Objective-C code back when I was earning a living as an iPhone app developer. (In general, I considered knowing C and C++ as a very important part of the upbringing of pre-Swift iOS developers.)
In hindsight, I have the impression that giving a copy of Scott Meyers’ “Effective C++” to each one of my colleagues would have been a better choice than penning an overly restrictive ad hoc document. These days, the C++ Core Guidelines live document by none other than Stroustrup and Herb Sutter (the last update of which, at the time of this writing, happened October last year) took over the role that “Effective C++” played 20 years ago, becoming the most authoritative coding guidelines document available today.
Scott decided to retire from the C++ world in 2015, so let this article be a belated “thank you” from a developer who benefitted tremendously from his outstanding contributions to the field. We need more people like him.
If you want to continue your exploration of C++, I can recommend the eponymous book by Stroustrup himself, or if you are in a hurry, its shorter version. A decidedly more advanced reading, Andrei Alexandrescu’s “Modern C++ Design: Generic Programming and Design Patterns Applied” is one of the most extensive works on template metaprogramming ever written, a book highly recommended by Scott Meyers himself. The first chapter of the (often-mentioned in the pages of this magazine) book “Masterminds of Programming” by Federico Biancuzzi and Shane Warden contains an extensive interview of Bjarne Stroustrup.
If you are interested in the genesis and history of the language, you will be happy to learn that C++ is the only programming language to have been featured in three consecutive editions of the famous “History of Programming Languages” (HOPL) conferences, created by the late Jean Sammet. The three papers, all written and delivered by Stroustrup himself, are available online: “A history of C++: 1979–1991” (HOPL II, 1993), “Evolving a language in and for the real world: C++ 1991-2006” (HOPL III, 2007), and “Thriving in a crowded and changing world: C++ 2006–2020” (HOPL IV, 2021). At the current rate, HOPL V will take place in 2035, so you have time to read them all.
C++ is a complex yet rewarding language, and it is time for software developers to understand that it has changed for good, that it has all the traits of a “modern” language, and that it definitely deserves a place in the programming arsenal of each one of us in this industry.
Cover photo by the author.