Blog 4 min read

C++ Standards and Best Practices: The Perfect Combo

Share this article
C++ Standards and Best Practices: The Perfect Combo

C++ stagnated for many years, and many developers were convinced that the language would meet the same fate as COBOL, Fortran, and VB6. Instead, against all odds, C++ rose from the ashes, and the new standards are significantly changing the way the language is used.

The evolution of C++, with the addition of many useful features, does not mean that the C++98 standard was a bad one. Indeed, it provided many useful features for developing all kinds of applications. There are many well-designed older C++ projects whose code is easy to maintain and evolve.

For example, Doom, developed by John Carmack, is a well-designed C++ game that uses only the basic mechanisms of the C++98 standard.

Here's the kind of testimonial you can find when searching for articles about Doom 3:

I spent a bit of time going through the Doom3 source code. It’s probably the cleanest and nicest looking code I’ve ever seen.

The key to success was not the richness of the language, but rather following best practices that keep the code easy to read, maintain, and evolve.

It’s true that not all developers have John Carmack’s skills, and maybe they need a more powerful language that helps them focus on the business layer of their applications. However, even if you use the most powerful programming language, if you adopt bad practices, the code will be very difficult to understand or maintain.

Even with a complex programming language such as assembly, we can still have clean code: the Prince of Persia game is proof that keeping it simple works even when using a low-level programming language.

Prince of Persia was originally developed by Jordan Mechner and released in 1989 for the Apple II; it represented a great leap forward in the quality of animation seen in video games. On April 17, 2012, Jordan Mechner released the source code of Prince of Persia. When exploring its codebase, we can see that:

  • The naming is clear and easy to understand.
pp2
  • The code is split into many small subroutines.

The 6502 assembly language is very low-level, and the “Divide and Conquer” principle is applied to make the code easier to understand and maintain. Indeed, the code is split into many small subroutines, making it easier to read and maintain. Here’s an example of a small subroutine from its source code:

pp3

Returning to the new C++ standards, we can write clean code using all the useful new features. On the other hand, if we follow bad practices, we can end up with code that is difficult to understand and maintain. For example, this interesting post talks about the overuse of the auto keyword.

Bjarne Stroustrup and Herb Sutter recognized the need for basic guidelines for writing efficient modern C++ code. A few years ago, they introduced the “C++ Core Guidelines”. Here’s the motivation behind introducing the guidelines, from their GitHub repository:

This document is a set of guidelines for using C++ well. The aim of this document is to help people to use modern C++ effectively. By "modern C++" we mean C++17, C++14, and C++11. In other words, what would you like your code to look like in 5 years' time, given that you can start now? In 10 years' time?

The guidelines are focused on relatively high-level issues, such as interfaces, resource management, memory management, and concurrency. Such rules affect application architecture and library design. Following the rules will lead to code that is statically type safe, has no resource leaks, and catches many more programming logic errors than is common in code today. And it will run fast -- you can afford to do things right.

Having guidelines is useful, but developers generally cannot spend hours manually reviewing code to check compliance with them. For this reason, it is better to use a tool to perform these checks.

clang-tidy is the tool to use; it provides many interesting checks, including checks of some CppCoreGuidelines rules.

To summarize, these new C++ standards are a welcome development—thanks to everyone in the C++ community who contributed to making them possible, as this was no easy task. However, without basic best practices and guidelines, code can quickly become unreadable, unmaintainable, and difficult to evolve.

Share this article