Wertvolle Empfehlungen auf der Meeting C++ 2013

Veranstaltungsberichte  –  17 Kommentare
Applaus für das Organisationskomitee mit Jens Weller in der Mitte

Anfang November fand zum zweiten Mal die Konferenz Meeting C++ statt. Sie bot einen bunten Strauß aus Richtlinien und Empfehlungen. Außerdem konnten die Teilnehmer wichtige Boost-Bibliotheken kennen lernen, sich über aktuelle Entwicklungen zu C++14 informieren sowie mehr über Tricks zur Template-Meta-Programmierung oder Näheres zu Entwicklungswerkzeugen wie CMake oder Visual Studio erfahren.

Jens Weller hatte die Veranstaltung im vergangenen Jahr aus der Taufe gehoben und sich für die zweite Auflage wieder für Düsseldorf als Veranstaltungsort entschieden. Vor Ort trafen 200 Entwickler – die meisten aus Europa, einige wenige aus den USA und Asien – aufeinander, um sich in gut 20 Vorträgen zu C++ zu informieren.

Im Eröffnungsvortrag stellte Eric Niebler, Mitglied im C++-Standardisierungskomitee und im Boost Steering Committee, Richtlinien für ein gutes Design von C++11-Bibliotheken vor. In C++11 sollten Eingangsparameter an Funktionen als Kopie und nicht als const& übergeben werden, wenn sie innerhalb der Funktion einer anderen Variablen zugewiesen werden. Dadurch lässt sich ein Kopiervorgang, wie er sonst notwendig wäre, durch zwei Moves ersetzen – vorausgesetzt, der Aufrufer übergibt den Parameter per Move an die Funktion. Diese Richtlinie ist laut Niebler insofern bemerkenswert, als dass Entwickler in Vor-C++11-Code Eingangsparameter üblicherweise immer als const& übergaben – unabhängig davon, ob der Parameter einer anderen Variable zugewiesen wurde oder nicht.

C++11 ändert Niebler zufolge die Dreier- zur Fünferregel. Erstere besagte, dass Entwickler explizit einen Destruktor, einen Copy-Konstruktor und einen Zuweisungsoperator definieren sollten, auch wenn sie ursprünglich planten, lediglich eine dieser drei Funktionen zu definieren. Die Fünferregel fügt diesen Funktionen den Move-Konstruktor und den Move-Zuweisungsoperator hinzu. In C++11 sollte eine Klasse also entweder keine oder alle fünf Funktionen explizit definieren.

Zur besseren Versionierung bietet C++11 Inline-Namensräume an, erklärte der Eröffnungsredner. Ändert sich eine Bibliothek im Laufe der Zeit, werden die verschiedenen Versionen idealerweise in ihren eigenen Namensräumen definiert – wie in foo::v1 und foo::v2. Der Namensraum der Standardversion sollte dann mit inline definiert werden. Ist zum Beispiel foo::v2 als Inline-Namensraum angegeben, sind alle Definitionen aus diesem Namensraum automatisch in foo verfügbar. Während sich das auch mit dem Schlüsselwort using bewerkstelligen lässt, ist inline für Template-Spezialisierungen entscheidend. So ist es nicht möglich, Spezialisierungen in foo vorzunehmen, wenn ein Template aus einem Unternamensraum wie foo::v2 stammt – außer dieser ist als inline definiert.

Regeln für ein einfacheres C++

Im Vortrag "Einfacheres C++ mit C++11/14" von Peter Sommerlad, Professor für Informatik und ebenfalls Mitglied im Standardisierungskommitee, bekamen Konferenzteilnehmer weitere, zum Teil weitgehende und nicht immer unumstrittene Empfehlungen zu hören. Die einzige Funktion in einem Programm, die auf globale Variablen zugreifen sollte, ist main(). Soll eine andere Funktion auf eine globale Variable Zugriff haben, sollte diese als Parameter an die Funktion übergeben werden. Diese Regel stellt das Entwickeln von Unit-Tests für Funktionen sicher. Das Vorgehen ist einfacher, wenn Funktionen nicht intern auf festkodierte globale
Variablen zugreifen.

Lokale Variablen sollten laut Sommerlad mit dem Schlüsselwort auto definiert werden. Da auto-Variablen zu initialisieren sind, verhindert diese Regel, dass versehentlich mit nicht initialisierten Variablen gearbeitet wird. Den Typ der auto-Variablen leitet man über den Wert ab, mit dem die Variable initialisiert wird. Da der Typ vom Initialisierungswert abhängt, ist die Angabe des Typs anstelle des Schlüsselworts auto überflüssig. Die Initialisierung soll außerdem über geschweifte Klammern erfolgen – über die mit C++11 eingeführte uniforme Initialisierung.

Algorithmen aus der Standardbibliothek oder anderen Bibliotheken sollten Sommerlad zufolge for- oder while-Schleifen vorgezogen werden. So lassen sich auch Funktionen, die sonst Schleifen enthalten, als eine lineare Abfolge von Funktionsaufrufen implementieren. Dynamisch reservierte Objekte sollten des Weiteren in Smartpointern verankert werden, die diese automatisch mit delete() freigeben. Sommerlad empfahl ferner, den Einsatz von new() ebenfalls einzuschränken. Stattdessen sollten Funktionen wie std::make_shared() und ab C++14 std::make_unique() eingesetzt werden.

Die Fünferregel lässt sich laut Sommerlad durch eine Nullerregel ersetzen, indem Klassen so implementiert werden, dass keine einzige der fünf speziellen Funktionen zu definieren ist. Das kann durch einen konsequenten Einsatz von Smartpointern geschehen.

In der Tiefe suchen

Edouard Alligand - Skalieren mit C++11

Im Vortrag "Skalieren mit C++11" ging Edouard Alligand, Gründer von Bureau 14 und Entwickler einer hochskalierenden Datenbank, darauf ein, wie Anwendungen die Leistungsfähigkeit aller verfügbaren Prozessorkerne ausnutzen können: Grundsätzlich sollten so wenig globale Ressourcen wie möglich verwendet werden. Im Idealfall teilen sich Threads keine Ressourcen. Zu diesen globalen Ressourcen gehören zum Beispiel der Referenzzähler in std::shared_ptr<>. Der Einsatz dieses Smartpointers ist demnach mit Vorsicht zu genießen.

Die Anzahl der Zugriffe auf Ressourcen, die sich mehrere Threads teilen, sollte minimiert werden. Ist es zum Beispiel notwendig, dass Threads mehrere Zahlen zu einer globalen Variable hinzuaddieren, ist es angebracht, dass jeder Thread zuerst seine Zahlen aufsummiert, um dann lediglich dieses Zwischenergebnis zur globalen
Variable hinzuzuaddieren.

Es ist außerdem laut Alligand wichtig, die Größe der Cache-Zeilen von Zielprozessoren zu kennen. Da Schreibzugriffe per Cache-Zeile atomar sind, versuchen idealerweise nicht mehrere Threads gleichzeitig in Speicherbereiche zu schreiben, die über die gleiche Cache-Zeile angesprochen werden. Dazu kann es notwendig sein, Compiler-spezifische Anweisungen zur Speicherausrichtung zu verwenden.

Zum guten Schluss

Abschlussveranstaltung mit Tony van Eerd

Die Schlussveranstaltung war ein Vortrag von Tony van Eerd, der bei BlackBerry für die C++-APIs verantwortlich ist. Er spannte einen weiten Bogen von Kunst über Benutzeroberflächen – nicht nur virtuelle am Computer – hin zu C++-Code. Ein Zitat von Picasso brachte die Komplexität und Flexibilität von C++ und die damit verbundenen Schwierigkeiten und Möglichkeiten auf den Punkt: "Learn the rules like a pro, so you can break them like an artist."

Der Veranstalter hat angekündigt, die Meeting C++ auch im kommenden Jahr zu veranstalten – dann möglicherweise in Berlin. Die Konferenz soll wie bisher im November stattfinden. Der Call for Papers wird im Frühjahr sein. Es ist angedacht, dass Studenten Eintrittskarten zu ermäßigten Preisen kaufen können. Auf der Konferenz-Website stehen mittlerweile die Präsentationen der Meeting C++ 2013 zum Download. (ane)

Boris Schäling
ist aktives Mitglied der Boost-Community und Autor des Buchs "Die Boost C++ Bibliotheken".