Was ist modernes C++?

Wir sprechen oft von klassischem und modernem C++. Doch was ist modernes C++ überhaupt? Es gibt eine einfache und eine nicht so einfache Antwort ...

In Pocket speichern vorlesen Druckansicht 1 Kommentar lesen
Lesezeit: 6 Min.
Von
  • Rainer Grimm
Inhaltsverzeichnis

Wir sprechen oft von klassischem und modernem C++. Was bedeutet das? Aber vor allem. Was ist modernes C++? Es gibt eine einfache und eine nicht so einfache Antwort. Die einfache Antwort ist: Modernes C++ liegt C++11, C++14 und C++17 zugrunde. Doch dieser Artikel und eine Serie weiterer Artikel drehen sich um die nicht so einfache Antwort.

Mit C++11 hatten wir eine Revolution. Diese wandelte sich mit C++14 zur Evolution und wird mit C++17 eine Evolution bleiben. Der Überblick zum Zeitstrahl der C++-Features macht meinen Punkt offensichtlich.

Wer auf die Menge der Features blickt, die wir seit C++11 erhalten haben, und sich deren Auswirkung überlegt, kommt zu der Schlussfolgerung: C++ vor und seit 2011 sind verschiedene Sprachen. Die erste wird klassisches C++, die zweite modernes C++ genannt. Daher ist die idiomatische Art und Weise, in C++ vor 2011 und seit 2011 zu programmieren, vollkommen unterschiedlich.

Ich bin nicht alleine auf meine Suche. Es gibt bereits großartige Ressourcen. Hier sind zwei:

Die "C++ Best Practices" von Jason Turner sind eine "Collaborative Collection of C++ Best Practices". Sie ist eine sehr wertvolle Ressource für moderne Softwareentwicklung mit C++ und für allgemeine Betrachtungen zu gutem C++-Code. Die allgemeinen Betrachtungen schließen Sicherheit, die Wartung, Portierbarkeit, Gleichzeitigkeit und Performanz von Code ein.

Heute will ich mich nicht auf die allgemeinen Betrachtungen konzentrieren, sondern auf die Sammlung von Werkzeugen, die Jason in "C++ Best Practices" anbietet.

Seine "C++ Best Practices" enthalten eine Sammlung von Werkzeugen für

  • Versionskontrolle
  • Bauen von Software
  • Continuous Integration
  • Compiler wie gcc, clang und msvc
  • statische Code-Analyse-Werkzeuge
  • Laufzeit-Checker
  • Testing
  • Debugging

Wer die Entscheidung fällen muss, welche Werkzeuge er in seiner professionellen Softwareentwicklung einsetzt, dem gibt diese Quelle einen großartigen Überblick, welche Werkzeuge zur Verfügung stehen.

Mit diesem Artikel möchte ich einen Überblick geben, worüber ich insbesondere meine nächsten Artikel schreibe. Das dominante Thema werden die "C++ Core Guidelines" sein.

Dies sind die Ziele der Guidlelines: "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++11 and C++14 (and soon C++17)."

Die Herausgeber sind Bjarne Stroustrup und Herb Sutter. Die "C++ Core Guidelines" sind eine Menge von mehr als 100 Regeln. Diese Regeln werden in Hauptabschnitte (main section) und unterstützende Abschnitte (supporting section) aufgeteilt. Hier sind die Hauptabschnitte.

  • In: Introduction
  • P: Philosophy
  • I: Interfaces
  • F: Functions
  • C: Classes and class hierarchies
  • Enum: Enumerations
  • R: Resource management
  • ES: Expressions and statements
  • E: Error handling
  • Con: Constants and immutability
  • T: Templates and generic programming
  • CP: Concurrency
  • SL: The Standard library
  • SF: Source files
  • CPL: C-style programming
  • Pro: Profiles
  • GSL: Guideline support library
  • FAQ: Answers to frequently asked questions

Ich will gerne mal einen näheren Blick auf den Einführungsabschnitt werfen. Dieser beschäftigt sich mit den folgenden Meta-Regeln.

  • In.target: Target readership
  • In.aims: Aims
  • In.not: Non-aims
  • In.force: Enforcement
  • In.struct: The structure of this document
  • In.sec: Major section

Lasst mich die Meta-Regeln paraphrasieren. Der adressierte Leser (target reader) ist selbst ein C-Programmierer. Das Ziel (aim) der Regeln ist es, Entwicklern zu helfen, modernes C++ (C++11, C++14 und bald C++17) einzusetzen. Die Regeln betonen statische Typsicherheit und sicheres Ressourcenmanagement. Er sollte diese Regeln verstehen, den sie sind präskriptiv. Neben den Zielen, die sie verfolgen, gibt es Ziele, die sie nicht verfolgen (non-aims).

Das Ziel der Regeln ist es, weder minimal noch orthogonal zu sein, noch sollen sie sich einfach nacheinander lesen lassen oder ein Tutorial ersetzen. Die Regeln sind auch weder eine Anleitung, alten C++-Code in modernes C++ zu portieren, noch sollen sie sehr exakt sein oder eine vereinfachte Teilmenge von C++ beschreiben. Weder sind sie wertfrei noch perfekt. Jede Regel hat einen Abschnitt, der sich mit ihrer Durchführung (enforcement) beschäftigt, denn die Regeln sollen den Entwicklern helfen, ihren Code zu vereinheitlichen und zu modernisieren. Die Regel folgen einer einheitlichen Sturktur (structure). Die Struktur besteht aus den Punkten

  • Rule
  • Rule Reference Number
  • Reason
  • Examples
  • Alternatives
  • Exceptions
  • Enforcement wie die Regel automatisch geprüft werden kann
  • See also
  • Notes
  • Discussion

Um ehrlich zu sein, diese Struktur erinnert mich sehr an die (Design-)Pattern-Literatur.

Um die Absicht der Struktur klar auf den Punkt zu bringen, folgt als einfaches Beispiel die Regel R.22. Das R steht für Ressourcemanagement.

Falls du ein Objekt erzeugst und an den Konstruktor des shared_ptr übergibst, wendest du mit hoher Wahrscheinlichkeit mehr als eine Speicherallokation und später eine Speicherdeallokation an, den das Objekt und der Referenzzähler müssen separat allokiert werden. Das ist nicht der Fall, falls du make_shared() verwendest.

shared_ptr<X> p1 { new X{2} }; // bad
auto p = make_shared<X>(2); // good

Die make_shared()-Version verwendet X nur einmal. Daher ist diese Variante im Allgemeinen kürzer und schneller als die Variante mit dem expliziten new-Aufruf.

Gib eine Warnung aus, falls ein shared_ptr durch einen new- und nicht durch einen make_shared-Aufruf erzeugt wird.

Bevor ich diesen Artikel beende, will ich ein paar Worte zu meiner Motivation sagen, über modernes C++ und insbesondere über die "C++ Core Guidlines" zu schreiben. Während ich diese Zeilen schreibe, fällt mir aber auf, dass ich meine Motivation nicht auf ein paar Sätze reduzieren will. Daher weißt du bereits, wovon mein nächster Artikel handelt. ()