C++ Core Guidelines: Profiles

Contents[Show]

Informally, profiles are a subset of rules of the C++ core guidelines for specific concerns such as type safety, bounds safety, and lifetime safety. Thanks to the guideline support library, they can be checked

checklist 911840 1280

 There are two main reasons for the profiles:

  1. You have to deal with legacy code and you can not apply all rules of the C++ core guidelines in one step. You have to apply the rules step by step and use, therefore, some rules first and some rules later.
  2. Some related rules may be more important to your codebase than others. They aim for a specific goal such as the "avoidance of bounds error" or the "correct usage of types". These related rules are called profiles.

Here is the formal definition of profiles from the C++ core guidelines:

  • Profile : A “profile” is a set of deterministic and portably enforceable subset rules (i.e., restrictions) that are designed to achieve a specific guarantee. “

Two terms in the definition are quite interesting:

  • Deterministic: Local analysis can analyse the rule it can be implemented by a compiler.
  • Portably enforceable: Different tools on different platforms give you the same answer.

Now, the question is: When does your code conform to a profile? The answer is simple: It has to be warning-free regarding a profile. There exist three profiles:

According to the C++ core guidelines, additionally, profiles may follow in the future regarding topics such as undefined, and unspecified behaviour. Before I continue in my next post with the three existing profiles, I have to explain what the difference between undefined and unspecified behaviour is. Let's make a detour.

Undefined and unspecified behaviour

Here are the definitions from the current C++20 draft. The draft is written in American English.

  • Undefined behavior (3.27):  behavior for which this document imposes no requirements.
  • Unspecified behavior(3.28): behavior, for a well-formed program, construct and correct data, that depends on the implementation.

Okay, let me give you more explanation and a few examples:

Undefined behaviour

Informally said when your program has undefined behaviour you can not give any guarantees about your program  The result may be the expected result, you may get the wrong result, the compilation may break, or you get a runtime error. The behaviour may depend on the platform, the compiler, the compiler version, the optimisation level, or the state of the used computer. I could extend this list forever but I will stop here. The action you have to take is quite simple: Fix the undefined behaviour!

To make it more concrete, here a few typical examples of undefined behaviour.

  • Access to containers such as C-arrays or STL-containers out of bounds
  • Use of an uninitialised variable
  • Dereferencing a null pointer
  • Division by zero
  • Undefined order of evaluation

Besides the last point, the listed undefined behaviours should be obvious.

Informally said, undefined order of evaluation of a subexpression A followed by a subexpression B means, that the compiler can evaluate the subexpression A and B in any order it wants. Now we need guarantees that A is sequenced_before B because if A is sequenced_before B, A is evaluated before B and we have these guarantees. For example logical operators, full expression (a = c;), invoking or returning from a function, or the end of an initialisation establish sequenced_before relations. Admittedly, this was a simplification to the order of evaluation. Read the details on cppreference.com

Maybe a small program helps your understanding. When I execute the following program with C++14, I get three warnings.

// undefinedBehaviour.cpp

#include <array>
#include <iostream>

int main(){

    std::cout << std::endl;
    
    std::array<int, 1> myArr{};                      // (0)

    int i{};                                         // (0)

    myArr[i] = i++;                                  // (1) 
    
    std::cout << i << "  " << i++ << std::endl;      // (1)
    
    std::cout << std::endl;

    int n = ++i + i;                                 // (2)

    std::cout << "n: " << n << std::endl;  

    std::cout << std::endl;

}

I use in the line (0) curly braces to initialise both data-types. The three expressions in line (1) and line (2) have undefined behaviour with C++14. The reason is that each expression is fully evaluated at the end of the expression. The semicolon is in these cases the end of the expression. The Clang compiler gives self-explanatory warnings.

 undefinedBehaviour

Unsequenced evaluation means that the operations may happen in any order and even overlap. This is even possible in a single-threaded execution because the underlying assembler instruction may interleave. Sorry, this was not the full truth. The lines (1) have undefined behaviour in C++14 but unspecified behaviour in C++17.

Unspecified behaviour

Unspecified behaviour means that the implementation is not required to document which behaviour occurs. For example, it is unspecified in which order the arguments of a function are evaluated.

Here is an interesting example, which has undefined behaviour in C++14 but unspecified behaviour in C++17.


#include <iostream>

void func(int fir, int sec){
    std::cout << "(" << fir << "," << sec << ")" << std::endl;
}

int main(){
    int i = 0;
    func(i++, i++);
}

 

When I execute the program, the output differs between GCC and Clang. Neither do you get the same result nor are the arguments evaluated left to right.

 

GCC

gcc

 

 

 

Clang

clang

 

 
 

 

Unspecified behaviour in C++17 gives you the guarantee that each argument is first fully evaluated before the other argument is evaluated. But you have still no guarantee in which order it is done.

What's next?

After this necessary detour to undefined and unspecified behaviour, I will write in my next post about the three profiles type safety, bounds safety, and lifetime safety.

The election of the pdf packages is made:

You can see the details of the election in the provided links. The pdf packages will be available in 1 - 2 weeks.

 
 
 

Thanks a lot to my Patreon Supporters: Paul Baxter,  Meeting C++, Matt Braun, Roman Postanciuc, Venkata Ramesh Gudpati, Tobias Zindl, Marko, Ramesh Jangama, G Prvulovic, Reiner Eiteljörge, Benjamin Huth, Reinhold Dröge, Timo, Abernitzke, Richard Ohnemus , Frank Grimm, Sakib, Broeserl, and António Pina.  

 

Thanks in particular to:
 
crp4

 

   

Get your e-book at Leanpub:

The C++ Standard Library

 

Concurrency With Modern C++

 

Get Both as one Bundle

cover   ConcurrencyCoverFrame   bundle
With C++11, C++14, and C++17 we got a lot of new C++ libraries. In addition, the existing ones are greatly improved. The key idea of my book is to give you the necessary information to the current C++ libraries in about 200 pages.  

C++11 is the first C++ standard that deals with concurrency. The story goes on with C++17 and will continue with C++20.

I'll give you a detailed insight in the current and the upcoming concurrency in C++. This insight includes the theory and a lot of practice with more the 100 source files.

 

Get my books "The C++ Standard Library" (including C++17) and "Concurrency with Modern C++" in a bundle.

In sum, you get more than 600 pages full of modern C++ and more than 100 source files presenting concurrency in practice.

 

Get your interactive course

 

Modern C++ Concurrency in Practice

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

educative CLibrary

Based on my book "Concurrency with Modern C++" educative.io created an interactive course.

What's Inside?

  • 140 lessons
  • 110 code playgrounds => Runs in the browser
  • 78 code snippets
  • 55 illustrations

Based on my book "The C++ Standard Library" educative.io created an interactive course.

What's Inside?

  • 149 lessons
  • 111 code playgrounds => Runs in the browser
  • 164 code snippets
  • 25 illustrations

Add comment


My Newest E-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)

Subscribe to the newsletter (+ pdf bundle)

Blog archive

Source Code

Visitors

Today 2184

All 3003879

Currently are 159 guests and no members online

Kubik-Rubik Joomla! Extensions

Latest comments