Modern C++ and the Weight of Progress

Recent trip reports (1,2) from the February/March C++ Standard Committee meeting revealed a few details concerning the upcoming C++17 standard. It looks like a number of features, including modules, concepts, ranges, and coroutines won’t be making it in. If you’ve paid attention at all to the C++ community over the past year or two, you’ll know that these were some of the things that folks were most excited about. For a long while, there was a sense that these features were a done deal. They garnered a lot of buzz even before C++14’s paint dried. Talks have been given on them. Blogs have been written about them. Compiler vendors jumped on the bandwagon and started releasing early implementations for community review. The C++ train has had a lot of momentum, so the expectations were high. And now I suspect that many C++ aficionados are feeling a tad bit jilted.

Truth is – I’m kind of relieved.

We’ve come a long way since C++98. There have been significant improvements to the language. I can’t deny that. But with the good comes the bad, or at the very least the not-so-great. Every time a new standard is released, we get more cruft, more weird keywords, and more things that don’t feel like C++ (You thought the square bracket lambda syntax was weird? Wait until you get a load of the annotations coming in C++17!). With every new standard, the learning curve gets a bit steeper.

A couple of years ago, Mike Acton made the offhand remark in his CppCon 2014 talk “Data-Oriented Design and C++”(23:35), “I can just imagine this meeting tonight on, you know, what else can the C++ committee add to the fucking lang, er, add to the language to make it solve our problems for us, right?” It was funny. I laughed. And I totally agreed with the spirit of what he was saying.

The C++ Standards Committee has, as a matter of principle, strived to maintain backwards compatibility with each iteration of the C++ standard. It’s an honorable goal, and one I think is important. Certainly, some of the largest and oldest active codebases in the world are written in C++. So for many, breaking language changes would be a non-starter. But how do you evolve a language and keep its complexity manageable without removing something? Perhaps you can’t.

Scott Meyers suggested in CppCast Episode #26 that maybe it’s time to finally remove obsolete language features. It’s an interesting idea. But it should send a shiver down the spine of any developer who’s had to maintain a large, legacy codebase. Add in the need to support multiple platforms and compilers, things get even scarier. It’s a path rife with compiler divergence and inconsistencies. Maintaining code would only get harder. It’s a direction that I think is unpalatable for most. Not to mention at what point is C++ no longer C++?

So time will march on and C++ will continue to have, as it always has, a reputation for being complicated. Since C++11, a new standard has been released every three years. Herb Sutter’s C++17 trip report mentions the committee is considering shortening the release cycle to two years, promising bigger, better, faster, stronger. And messier.

I’m slightly discouraged by the whole thing. In an era when it’s common to build applications using a heterogeneous assortment of technologies, why does C++ feel the need to become everyone’s everything language?

Engineers are in the business of getting things done. We strive for elegant, simple solutions that clearly communicate our ideas and that are easy to maintain. For C++ developers, it’s unfortunate that the complexity of our tool is overshadowing the work we do. Most folks don’t have the time and energy to keep up with the language changes. Those folks are in the trenches, hard at work building real applications. The irony here, of course, is that these are the very folks the latest and greatest language features were intended to help.