This preface serves one purpose: to give you, dear reader, the necessary background to get the most out of this book. This background includes technical details about me, my writing style, my motivation for writing this book, and the challenges of writing such a book. If you want to skip this section, fine, but at least read the Acknowledgments section.
I promise, only a few conventions.
The authors of the C++ Core Guidelines often refer to them as rules. So do I. In the context of this book, I use both terms interchangeably.
Bold |
Sometimes I use bold font to emphasize important terms. |
Italic |
Italics designate hyperlinks (eBook only). |
|
Code, instructions, keywords, names of types, variables, functions, and classes are displayed in monospace font. |
I use boxes with a bullet list for the information concluding each chapter.
Often rules are related to other rules. I provide this valuable information at the end of the chapter if necessary.
I dislike using directives and declarations because they hide the origin of the library functions. Due to the limited length of a page, I have to use them from time to time. I use them in such a way that the origin can always be deduced from the using directive (using namespace std;
) or the using declaration (using std::cout;
). Not all headers are displayed in the code snippets. Boolean values are displayed with true
or false
. The necessary I/O manipulator std::boolalpha
is mostly not part of the code snippets.
Three dots (...
) in the code snippets stand for missing code.
When I present a complete program as a code example, you will find the name of the source file in the first line of the code. I assume that you use a C++14 compiler. If the example needs C++17 or C++20 support, I mention the required C++ standard after the name.
I often use markers such as // (1)
in the source file to ease my explanations. If possible, I write the marker in the cited line or, if not, one line before. The markers are not part of the more than 100 source files that are part of the book (available from https://github.com/RainerGrimm/CppCoreGuidelines). For layout reasons, I often adjusted the source code in this book.
When I use examples from the C++ Core Guidelines, I often rewrite them for readability by adding namespace std
if it is missing, or unify the layout.
This subjective observation is mainly based on my more than 15 years of experience as a trainer for C++, Python, and software development in general. In the last few years, I was responsible for the team and the software deployed on defibrillators. My responsibility included regulatory affairs for our devices. Writing software for a defibrillator is extremely challenging because they can cause death or serious injury for the patient and the operator.
I have a question in mind that we should answer as a C++ community. This question is: Why do we need guidelines for modern C++? Here are my thoughts, which consist for simplicity reasons of three observations.
C++ is, in particular for beginners, an inherently complex language. This is mainly because the problems we want to solve are inherently complicated and often complex as well. When you teach C++, you should provide a set of rules that work for your participants in at least 95% of all use cases. I think about rules such as
Let the compiler deduce your types.
Initialize with curly braces.
Prefer tasks over threads.
Use smart pointers instead of raw pointers.
I teach rules such as the ones mentioned in my seminars. We need a canon of best practices or rules in C++. These rules should be formulated positively and not negatively. They should declare how you should write code and not what should be avoided.
I’m not worried about the sheer amount of new features that we get with each new C++ standard every three years. I’m worried about the new ideas that modern C++ supports. Think about event-driven programming with coroutines, lazy evaluation, infinite data streams, or function composition with the ranges library. Think about concepts, which introduce semantic categories to template parameters. It can be quite challenging to teach C programmers object-oriented ideas. When you shift, therefore, to these new paradigms, you have to rethink and presumably change the way you solve your programming challenges. I assume that this plethora of new ideas will, in particular, overwhelm professional programmers. They are the ones who are used to solving the problems with their classical techniques. With high probability, they fall into the hammer-nail trap.
In the end, I have a strong concern. In safety-critical software development, you often have to stick to guidelines. The most prominent are MISRA C++. The current MISRA C++:2008 guidelines were published by the Motor Industry Software Reliability Association. They are based on the MISRA C guidelines from the year 1998. Initially designed for the automotive industry, they became the de facto standard for the implementation of safety-critical software in the aviation, military, and medical sectors. As MISRA C, MISRA C++ describes guidelines for a safe subset of C++. But there is a conceptual problem. MISRA C++ is not state of the art for modern software development in C++. It’s four standards behind! Here is an example: MISRA C++ doesn’t allow operator overloading. I teach in my seminars that you should use user-defined literals to implement type-safe arithmetic: auto constexpr dist = 4 * 5_m + 10_cm - 3_dm
. To implement such type-safe arithmetic, you have to overload the arithmetic operators and the literal operators for the suffixes. To be honest, I don’t believe that MISRA C++ will ever evolve in lockstep with the current C++ standard. Only community-driven guidelines such as the C++ Core Guidelines can face this challenge.
Let me share the essential lines of my e-mail discussion in May 2019 with Bjarne Stroustrup and Herb Sutter telling them that I wanted to write a book about the C++ Core Guidelines: “I’m an absolute fan of the value which is inside the C++ Core Guidelines because my strong belief is that we need guidelines for the correct/safe usage of modern C++. I often use examples or ideas from the C++ Core Guidelines in my C++ classes. The format reminds me of the MISRA C++ or AUTOSAR C++14 rules which is presumably intentional, but this is not the ideal format for a big audience. I think that more people would read and reason about the guidelines if we had a second document which describes the general ideas of the guidelines.”
I want to add a few remarks to these previous conversations. In the last few years, I wrote on my German and English blogs more than a hundred posts about the C++ Core Guidelines. Additionally, I write for the German Linux-Magazin a series on the C++ Core Guidelines. I do this for two reasons: First, the C++ Core Guidelines should become better known, and second, I want to present them in a readable form, extended with background information if necessary.
Here is my challenge: The C++ Core Guidelines consist of over five hundred guidelines, most of the time just called rules. These rules are designed with static analysis in mind. Many of the rules are lifesaving for a professional C++ software developer, but also many of the rules are quite special, often incomplete or redundant, and sometimes the rules even contradict. My challenge is to boil these valuable rules down to a readable, even entertaining, story, removing the esoteric stuff and filling the gaps if necessary. In the end, the book should contain the rules that are mandatory for a professional software developer in C++.
Panta rhei, or “everything flows,” from the Greek philosopher Heraclitus stands for the challenge I’m faced with while writing this book. The C++ Core Guidelines are a GitHub-hosted project with more than 200 contributors. While I was writing this book, the source I was basing my writing on may have changed.
The guidelines already include C++ features, which may become part of an upcoming standard, such as contracts in C++23. To reflect this challenge, I made a few decisions.
I provide links in the electronic version of this book to the mentioned C++ Core Guidelines so you can quite easily refer to their origins.
My focus is on the C++17 standard. If appropriate, I include guidelines targeting the C++20 standard, such as concepts.
The C++ Core Guidelines evolve constantly, in particular as new C++ standards are published. So will this book. My plan is to update this book accordingly.
The structure of this book represents the structure of the C++ Core Guidelines. It has the corresponding major sections and parts of the supporting sections. In addition to the C++ Core Guidelines, I included appendixes, which provide concise overviews of missing topics, including C++20 or even C++23 features.
I still have not answered one question: how to read this book. Of course, you should start with the major sections, best from top to toe. The supporting sections provide additional information and introduce, in particular, the Guidelines Support Library. Use the appendixes as a kind of reference to get the necessary background information to understand the major sections. Without this additional information, this book would not be complete.