C++ Core Guidelines: The Philosophy

Today, I will dig a little bit deeper into the C++ Core Guidelines. In my last post about the C++ Core Guidelines, I wrote about the Introduction section. Today I write about the section that is "primarily for humans". This is the most general section and is called Philosophy. The rules are so general that you can apply them to each programming language.


Only to remind you. The C++ Core Guidelines consists of 350 rules. They a grouped in the following sections.

Let's look at each of the 13 philosophy rules. They should provide the rationale for all 350 rules.


 800px Head Platon Glyptothek Munich 548

The following 13 rules cannot be checked completely. Here are they.

If possible, I will provide examples from the C++ Core Guidelines to each of the rules.


Rainer D 6 P2 540x540Modernes C++ Mentoring

Stay informed about my mentoring programs.



Subscribe via E-Mail.

Express ideas directly in code

A method should express its intent. Have a look here.

class Date {
    // ...
    Month month() const;  // do    
    int month();          // don't
    // ...


Neither does the second method month express that it will not change the instance nor does it return a Month object.

The same reasoning often holds for explicit loops versus algorithms of the Standard Template Library (STL).

int index = -1;                    // bad
for (int i = 0; i < v.size(); ++i) {
    if (v[i] == val) {
      index = i;

auto p = find(begin(v), end(v), val);  // better


The meta-rule is obvious. You should know and use the algorithms of the STL.

Write in ISO Standard C++

This rule reads quite simple and has a straightforward enforcement statement: "Use an up-to-date C++ compiler (currently C++11 or C++14) with a set of options that do not accept extensions."

Express intent

Your code should express its intent. What can we deduce from the three explicit and implicit loops?

for (const auto& v: vec) { ... }       (1)
for (auto& v: vec){ ... }              (2)
for_each(par, vec, [](auto v){ ... }); (3)


The elements of the container vec will not be modified in (1). On contrary, the elements in expression (2) will be modified. The algorithm for_each is executed with the parallel execution policy (par). That means the order of iteration does not matter.

Ideally, a program should be statically type-safe

You should strive for statically type-safe programs. Of course, that is not possible because there are problem areas in C++. The C++ Core Guidelines name the problem areas and possible solutions.

  • use std::variant (new with C++17) instead of unions
  • minimise the use of casts; use templates if possible
  • use gsl::span against array decay (if you pass an array to a function it will implicitly decay to a pointer) and range errors
  • minimise narrowing conversions (narrowing conversion is an implicit conversion including the loss of data accuracy; for example, a double becomes implicitly an int)

gsl stands for Guideline support library GSL. GSL is a small library to support the set of guidelines from the C++ Core Guidelines. I will write about the GSL in an upcoming post.

Prefer compile-time checking to run-time checking

All that can be done at compile time must not be done at run time. Since C++11 we have the function static_assert and the type-traits library. static_assert will check a predicate such as static_assert(sizeof(int) >= 4) at compile time. Thanks to the type-traits library, we can state powerful conditions about a type T at compile time: static_assert(std::is_integral<T>::value). Of course, if the check fails at compile-time, the compilation will fail with a readable error message. I already wrote about static_assert.

What cannot be checked at compile-time should be checkable at run time

This rule talks about hard-to-detect errors that should be avoided. The examples are about dynamically allocated arrays.

extern void f(int* p);
extern void f2(int* p, int n);
extern void f3(unique_ptr<int[]> uniq, int n);

f(new int[n]);                  (1)
f2(new int[n], m);              (2)
f3(make_unique<int[]>(n), m);   (3)


What's bad about the example? The call (1) does not pass the number of elements. (2) makes it possible to pass the wrong number of elements and (3) passes the ownership and the size separately. By bypassing a reference or a view (part of the gsl) you can overcome these issues.

Catch run-time errors early

Here are the enforcements for this rule:

  • Look at pointers and arrays: Do range-checking early and not repeatedly
  • Look at conversions: Eliminate or mark narrowing conversions
  • Look for unchecked values coming from the input
  • Look for structured data (objects of classes with invariants) being converted into strings

Don't leak any resource

Leaking resources are in particular critical for long-running programs. Resources may be a memory but also file handles or sockets. The idiomatic way to solve this issue is RAII. The idea of the RAII idiom is quite simple. You bind the acquisition and the release of a resource to the lifetime of a local object. Therefore, the resource will automatically be initialised in the constructor and released in the destructor. The acronym RAII stands for Resource Acquisition Is Initialization. Smart pointer and locks are based on this technique. Here are more details of RAII.

Don't waste time or space

The reason for this rule is quite promising: "This is C++". One example of the rule is a riddle.

What's wasted here?

void lower(string s)
    for (int i = 0; i < strlen(s); ++i) s[i] = tolower(s[i]);


Prefer immutable data to mutable data

There are a lot of reasons that speak for immutable data:

  • It's easier to reason about constants than about variables.
  • Constant have more optimisation potential.
  • Constants are free of data races.

Encapsulate messy constructs, rather than spreading through the code

Messy code is prone to bugs and harder to write. Therefore, you should encapsulate the low-level code in a function or a method and put a good interface around it.

Use supporting tools as appropriate

Computers are better than humans in doing boring and repetitive tasks. That means you should use static analysis tools, concurrency tools, and testing tools to automate these verifying steps.

Use support libraries as appropriate

That is quite easy to explain. You should go for well-designed, well-documented, and well-supported libraries. Therefore, you will get a well-tested and nearly error-free library and highly optimised algorithms from the domain experts. Two outstanding examples are the C++ standard library and the Guidelines Support Library.

What's next?

An interface is a contract between the service provider and the service user. There are 20 rules about interfaces in the C++ Core Guidelines. In the next post, I will have a closer look at interfaces.




Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Animus24, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Dominik Vošček, and Rob North.


Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, and Slavko Radman.



My special thanks to Embarcadero CBUIDER STUDIO FINAL ICONS 1024 Small


My special thanks to PVS-Studio PVC Logo


My special thanks to Tipi.build tipi.build logo


I'm happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.

Bookable (Online)


Standard Seminars (English/German)

Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.

  • C++ - The Core Language
  • C++ - The Standard Library
  • C++ - Compact
  • C++11 and C++14
  • Concurrency with Modern C++
  • Design Pattern and Architectural Pattern with C++
  • Embedded Programming with Modern C++
  • Generic Programming (Templates) with C++


  • Clean Code with Modern C++
  • C++20

Contact Me

Modernes C++,




+1 #1 kỳ nghỉ đông dương 2018-03-05 09:20
I'd like to thank you for the efforts you've put in writing this website.
I am hoping to see the same high-grade content from you in the future as well.
In fact, your creative writing abilities has encouraged me
to get my own, personal blog now ;)


Stay Informed about my Mentoring


English Books

Course: Modern C++ Concurrency in Practice

Course: C++ Standard Library including C++14 & C++17

Course: Embedded Programming with Modern C++

Course: Generic Programming (Templates)

Course: C++ Fundamentals for Professionals

Interactive Course: The All-in-One Guide to C++20

Subscribe to the newsletter (+ pdf bundle)

All tags

Blog archive

Source Code


Today 3421

Yesterday 6374

Week 31045

Month 221121

All 11702275

Currently are 169 guests and no members online

Kubik-Rubik Joomla! Extensions

Latest comments