Das nächste große Ding: C++20

Modernes C++  –  21 Kommentare

C++20 wird der nächste große C++-Standard nach C++11 sein. Wie C++11 wird C++20 die Art und Weise ändern, wie wir in modernem C++ programmieren. Dies gilt vor allem für Ranges, Coroutinen, Concepts und Module. Um den nächsten großen Evolutionsschritt in C++ besser zu verstehen, möchte ich zuerst C++20 in den Kontext der bestehenden C++-Standards stellen.

Die C++-Standards

C++98

Ende der 80er-Jahre gab es mehrere unabhängige C++-Implementierungen. Daher legten Bjarne Stroustrup und Margaret A. Ellis 1989 in ihrem Buch The Annotated C++ Reference Manual (ARM C++) den Funktionsumfang von C++ fest. Darüber hinaus erfüllte ARM C++ noch eine zweite, wichtige Aufgabe. Er bildete die Grundlage für den ersten ISO-C++-Standard ISO/IEC 14882:1998 (C++98). C++98 besitzt sehr wichtige Features: Templates, die Standard Template Library (STL) mit ihren Containern und Algorithmen, Strings und IO-Streams.

C++03

Mit C++03 (ISO/IEC 14882:2003) erfuhr C++98 eine technische Korrektur, die so marginal ist, dass ich sie auf meinem Zeitstrahl nicht berücksichtige. In der Community wird C++03, das C++98 einschließt, schlicht Legacy C++ genannt.

TR1

Technical Report 1 (TR1) ist zwar kein offizieller Standard, beschreibt aber viele Komponenten, die in den offiziellen Standard C++11 aufgenommen wurden. Die neuen Bibliotheken zu regulären Ausdrücken, Smart Pointern, Hash-Tabellen oder Zufallszahlengeneratoren basieren alle auf TR1 und somit auf den entsprechenden Boost-Bibliotheken. Das Boost-Projekt, das von Mitgliedern des C++-Standardisierungskomitees gegründet wurde, ist die eigentliche Ideenwerkstatt für die aktuellen Erweiterungen der C++-Bibliothek. TR1 enthielt 13 Bibliotheken. Lediglich die speziellen mathematischen Funktionen mussten bis C++17 warten.

C++11

C++11 steht für den nächsten C++-Standard. Wir nennen diesen Standard schlicht Modern C++. Dieser Name steht auch für C++14 und C++17. C++11 besitzt viele Features, die fundamental die Art und Weise ändern, wie wir C++ programmieren. Zum Beispiel enthält C++11 die TR1-Komponenten, aber auch Move-Semantik, Perfect Forwarding, Variadic Templates, Lambdas oder constexpr. Das ist noch nicht alles. Mit C++11 besitzt C++11 ein Speichermodell als die fundamentale Grundlage von Concurrency und eine Multithreading-Schnittstelle. Falls du neugierig bist, hier sind meine Artikel zum Speichermodell und zur Multithreading im Allgemeinen.

C++14

C++14 ist ein kleiner Standard. Mit C++14 wurde C++ um Reader-Writer Locks, verallgemeinerte Lambdas und verallgemeinerte constexpr-Funktionen erweitert.

C++17

C++17 ist weder groß noch klein. Dieser Standard besitzt zwei herausragenden Features: die parallele STL und die Dateisystembibliothek. Über 80 Algorithmen der STL können nun mit einer sogenannten Ausführungsstrategie (execution policy). ausgeführt werden. Das heißt, das ein Aufruf der Form std::sort(std::execute::par, vec.begin(), vec.end()) ein Hinweis für die C++-Implementierung ist parallel zu sortieren. Zusätzlich lässt sich spezifizieren, ob die Sortierung sequentiell (std::execute::seq) oder vektorisiert (std::execute::par_unseq) ausgeführt werden soll. Entsprechend zu C++11, besaß Boost sehr starken Einfluss auf diesen C++-Standard. Boost erweiterte C++ um ein Dateisystem und die neuen Datentypen std::optional, std::variant und std::any. Hier sind meine Artikel zu C++17.

C++20

C++20 wird die Art und Weise wie wir C++ programmieren ähnlich fundamental ändern wie C++11. Dies gilt insbesondere für die großen Vier: Ranges, Coroutinen, Concepts und Module. Vor einem halben Jahr hätte ich noch von den großen 5 geschrieben. Leider wurden Contracts aus dem C++20 Standard in diesem Jahr in Köln entfernt. Ein Contract spezifiziert in einer exakten und überprüfbaren Weise eine Schnittstelle zu einer Softwarekomponente. Mein Artikel C++ Core Guidelines: Ein kleiner Umweg über Kontrakte liefert weitere Details. Ich sollte aber nicht über die Vergangenheit schreiben. Hier ist die strahlende Zukunft von C++.

Die Ranges-Bibliothek erlaubt es, die Algorithmen der Standard Template Library direkt auf den Container anzuwenden, diese mit dem aus der Unix-Shell bekannten Pipe-Operator zu verknüpfen und diese auf unendlichen Datenströmen zu definieren.

Mit Couroutinen unterstützt C++20 die asynchrone Programmierung. Damit werden sich in C++20 kooperatives Multitasking, unendliche Datenströme, Event-Schleifen oder auch Pipelines elegant umsetzen lassen.

Concepts sind eine Erweiterung von Templates von C++, mit denen sich semantische Kategorien für die Menge der zulässigen Datentypen definieren lassen. Dank Concepts wird das Anwenden und Definieren von Templates deutlich einfacher und ausdrucksreicher.

Module stellen eine Alternative zu Header-Dateien dar und versprechen viele Verbesserungen. Die Trennung von Header- und Sourcecodedateien aufzulösen, Präprozessor-Anweisungen zu eliminieren, bessere Kompilierungszeiten zu erzielen und einfacher Pakete zu schnüren.

Natürlich ist das bei weitem nicht der vollständige Inhalt von C++20. Hier kommen noch weitere Höhepunkte:

  • der Drei-Weg Vergleichsoperator: <=>
  • Stringliterale als Templateparameter
  • Kalender- und Zeitzonenerweiterungen für die chrono-Bibliothek
  • std::span als ein View auf ein zusammenhängendes Array
  • constexpr virtuelle Funktionen
  • Neudefinition von volatile
  • Erweiterungen zu atomaren Variablen: std::atomic_ref<T> und std::atomic<std::shared_ptr<T>>>; warten mit atomaren Variablen
  • neue Synchronisationsmechanismen wie Semaphoren, Latches und Barriers
  • constexpr Container wie std::string und std::vector
  • ein verbesserter Thread mit std::jthread, der automatisch den join-Aufruf anstößt und gestoppt werden kann

Namensgebung

Okay, wie sollen wir das neue Kind nennen? Alle bestehenden C++-Standards besitzen bereits eine informellen Namen.

  • Legacy C++: C++98 und C++03
  • Modern C++: C++11, C++14 und C++17
  • <Platzhalter>: C++20, C++23, ...

Die Namensfindung ist schwierig. Im April stellte ich dieselbe Frage auf Twitter. Dies ist der Tweet,

und dies sind einige der mehr als 50 Antworten. Ich habe jeweils den Twitternamen des Vorschlagenden hinzugefügt.

  • indifferent penguin: Postmodern
  • Ricardo: next generation
  • Robert Ramey: The end of days
  • Daniel Oliveira: C++ Reloaded/Revolution/Exoteric
  • Michele Adduci: postmodern, post-postmodern, post-post-postmodern and so on
  • Thomas Rodgers: C++ Endgame
  • phlo81: new C++
  • Eric Niebler: co_modular C++
  • Martin Moene: Simple C++
  • Andrey Upadyshev: C++ 2
  • Joel F: Neon Genesis C++
  • Breno G: C+=2
  • Rasmus 'Elg' Bons: Futuristic C++
  • Sebastian Rampe: new c++
  • Dr James Smith: C++ Plus, C++ The Next Generation, C+++
  • Richard Robinson: ++C
  • Saurabh Purnaye: Ultra Modern cpp
  • Alican Gültekin: C+++
  • Alfonso Guerra: Neo-Futuris
  • Improv: now C++
  • Chris Blume Moderner C++
  • Satay Das: New modern C++
  • JustXtofl: post-20
  • Adem Budak: Postconceptual C++

Du siehst, es gibt eine leichte Tendenz für Postmodern. Vielleicht hast du ja eine bessere Idee.

Wie geht's weiter

Nun aber zu der Frage, die mich am meisten beschäftigt hat. Ich habe bereits rund zehn Artikel in den letzten Jahren geschrieben, die C++20 zum Thema hatten. Meine Frage war: Solch ich meine bestehenden Artikel einfach referenzieren oder soll ich sie nochmals veröffentlichen? Die erste Strategie ist unvollständig, die zweite Strategie überflüssig. Ich entschied mich dafür, einen dritten Weg einzuschlagen. Wenn möglich, werde ich daher bestehende Artikel als Startpunkt für einen neuen Artikel verwenden. Der Grund ist ganz einfach. Zuerst einmal nehme ich an, dass viele Leser meiner Artikel, die älter als ein Jahr sind, nicht kennen. Zum anderen haben sich viele Features verändert, seit ich meinen Artikel geschrieben habe. Meine entscheidende Idee ist es, dir eine vollständige Serie zu C++20 anzubieten. Natürlich beginne ich mit den großen Vier.

Der Button

im rechten Eck meines Blogs führt dich direkt zur Übersichtsseite meiner entstehenden und neuen Artikeln zu C++20.