List of figures

3.1 Dependency injection

4.1 Assembler instructions to the program constexpr.cpp

4.2 Returning a std::pair

4.3 The five ownership semantics

4.4 Displaying arbitrary characters

4.5 Causing a core dump

4.6 Returning a reference to a temporary

4.7 Summation with va_arg

4.8 Summation with fold expressions

5.1 Automatically generated special member functions

5.2 Double free detected with AddressSanitizer

5.3 Output of strange.cpp

5.4 Directly initializing in the class

5.5 Converting constructor

5.6 Wrong initialization order of member variables

5.7 Slicing

5.8 A class with a std::unique_ptr

5.9 delete the destructor

5.10 Calling a virtual function in the constructor

5.11 A virtual clone member function

5.12 A virtual clone member function without covariant return type

5.13 Shadowing of member functions

5.14 Different default arguments for virtual functions

5.15 dynamic_cast causes a std::bad_cast exception

5.16 Missing overload for int and MyInt

5.17 Using an explicit constructor

5.18 Implicit operator bool

5.19 Explicit operator bool

5.20 Undefined behavior with a “naked” union

6.1 The enumerators are too big for the underlying type

7.1 Resource Acquisition Is Initialization

7.2 Undefined behavior causes a core dump

7.3 Two owners with std::unique_ptr

7.4 Moving a std::unique_ptr

7.5 Cycles of smart pointers

7.6 Cycles of smart pointers

7.7 Lifetime semantics of smart pointers

8.1 Reusing names in nested scopes

8.2 Hiding member functions of a base

8.3 Change visibility with a using declaration

8.4 The most vexing parse

8.5 Narrowing conversion

8.6 Narrowing conversion detected

8.7 Usage of the function-like macro max

8.8 The null pointers 0, NULL, and nullptr

8.9 Unspecified behavior

8.10 Wrong casts with the Visual Studio compiler

8.11 Wrong casts with the GCC or Clang compiler

8.12 Modulo versus overflow with unsigneds and signeds

8.13 Detecting narrowing conversion

8.14 Underflow and overflow of a C-array

9.1 Performance of the Meyers singleton

9.2 Performance of the singleton based on acquire-release semantics

9.3 Performance of the singleton in the single-threaded case

9.4 Move semantics on a copy-only type

9.5 Invoking gcd at compile time and run time

9.6 The relevant assembler instructions to the algorithm gcd

9.7 std::deque

9.8 std::list

9.9 std::forward_list

9.10 Memory access for sequence containers on Windows

10.1 Four categories of variables

10.2 Data race detection with ThreadSanitizer

10.3 Overview of CppMem

10.4 A data race in CppMem

10.5 A deadlock due to multiple locked mutexes

10.6 Forgot to join a thread

10.7 A condition variable in action

10.8 A condition variable without a predicate

10.9 Shared ownership using a pointer

10.10 Shared ownership using a smart pointer

10.11 Thread creation on Linux

10.12 Thread creation on Windows

10.13 Using a temporary lock std::lock_guard

10.14 Using a named temporary std::lock_guard

10.15 Usage of std::transform_exclusive_scan

10.16 A value and an exception as message

10.17 Notifications with a task

12.1 A mutable variable

13.1 A function, a function object, and a lambda as sorting criteria

13.2 A function object with state

13.3 A lambda with state

13.4 Template argument deduction

13.5 A reference is not SemiRegular

13.6 Surprise with argument-dependent lookup

13.7 Surprises with argument-dependent lookup solved

13.8 std::enable_if

13.9 Comparing two accounts

13.10 Comparing two accounts with a binary predicate

13.11 Compiler error with a virtual member function

13.12 Calculating primes at compile time

13.13 Calculating the factorial of 5 at compile time

13.14 Calculating at run time and compile time

13.15 power as function and metafunction

13.16 Type comparisons

13.17 Correctness with the type-traits functions

13.18 Function versus template arguments

13.19 Modification versus new value

13.20 Recursion versus loop

13.21 Template specialization for conditional execution

13.22 Update versus new value

13.23 Simulating a return value

13.24 Case-insensitive search in a struct

13.25 Iterating through a few containers

13.26 Specialization and overloading of function templates

13.27 Specialization of function templates

14.1 Warnings with a C compiler

14.2 Errors with a C++ compiler

14.3 Different size of a char with a C++ compiler

14.4 Function overloading

15.1 Multiple definitions of a function

15.2 Linker error because of mismatch between function declaration and definition

15.3 Compiler error because of a mismatch between function declaration and definition

15.4 Cyclic dependencies among source files

16.1 Automatic management of memory

16.2 sizeof a C-array, a C++-array, and a std::vector

16.3 Accessing a nonexisting element of a std::string

16.4 Undefined behavior with a C-string

16.5 No memory allocation with std::string_view

16.6 Undefined behavior with printf

16.7 Performance with/without flushing on Linux

16.8 Performance with/without flush on Windows

18.1 Different return types in a function

18.2 Automatic managing of a device

A.1 Enable code analysis

A.2 Configure the applied rules

A.3 Automatic managing of a device

A.4 Suppress warnings

A.5 Check the C++ Core Guidelines exclusively

A.6 Check the C++ Core Guidelines with clang-tidy