Aus Linux-Magazin 10/2018

Modernes C++ in der Praxis – Folge 42

© Gleb TV, 123RF

Linux-Magazin-Autor Rainer Grimm stellt im ersten Teil seiner neuen C++-Serie Wegweiser durch den Dschungel der C++-Richtlinien auf. Die sollen Programmierern auf den richtigen Pfad im Umgang mit der komplexen Sprache bringen – manche wirken aber schon recht verwittert.

Was haben Misra C++ [1], Autosar C++ [2] und die C++-Core-Richtlinien [3] gemein? Die drei bekanntesten Regelwerke versprechen Programmierern Erfolgsrezepte für den sicheren Einsatz von C++. Stellt sich die Frage: Warum gibt es gleich drei? Diese und weitere beantwortet der Artikel.

Wozu gibt es überhaupt Regelwerke für C++? Gründe gibt es viele, der Artikel konzentriert sich aber auf drei Aspekte: C++ ist inhärent kompliziert, alle drei Jahre gibt es einen neuen C++-Standard, zudem kommt C++ gern in sicherheitskritischen Systemen zum Einsatz. Zugegeben, die drei Punkte basieren auf meiner persönlichen Erfahrung als langjähriger Software-Entwickler und Schulungsleiter für C++, ich möchte sie im folgenden aber plausibel machen.

Inhärent kompliziert

Programmiersprachen sollen immer komplexere Aufgaben lösen. Sie müssen eher abstrakte Themen wie Parallelität oder Sicherheit berücksichtigen, aber zugleich die konkreten Herausforderungen meistern, die das Internet der Dinge, Big Data, künstliche Intelligenz, Virtualisierung oder autonomes Fahren mitbringen.

Dieser Trend macht auch vor modernem C++ nicht Halt. Dessen Entwickler akzeptieren die Zielvorgaben, wollen dabei allerdings Performance-Einbußen und einen höheren Speicherverbrauch vermeiden. Sie streben also Abstraktion ohne Mehrkosten an.

Dieses Vorhaben dürfte wohl der Hauptgrund für die inhärente Vielschichtigkeit von C++ sein. Denn um die neuen Aufgaben zu bewältigen, dürfen die Abstraktionen zur Kompilierzeit nur minimale und zur Laufzeit gar keine Kosten verursachen. Das steigert die Komplexität der Programmiersprache.

Ständig neue Standards

Seit Version 11 ist C++ eine zeitgemäße Programmiersprache. Erstens bietet sie moderne Konzepte wie die Move-Semantik, automatisches Speichermanagement oder auch Multithreading-Unterstützung. Zweitens gibt es im Dreijahrestakt einen neuen C++-Standard.

Das erhöht die Anforderungen an Software-Entwickler. Sie müssen ihre Art, Probleme zu lösen, immer wieder hinterfragen. Neue Techniken wie Event-basiertes Programmieren, Bedarfsauswertung, Arbeiten mit unendlichen Datenstrukturen oder Funktionskomposition gilt es erst einmal zu verdauen. Mit C++20 warten schon neue Konzepte wie ein Typsystem für Templates in der Form von Concepts oder auch Design by Contract vor der Tür. In den nächsten Jahren soll C++ zudem auf dem Rücken der funktionalen Programmierung deutlich mathematischer und damit typsicherer werden.

Fokus auf Sicherheit

Die Domäne von C++ ist die systemnahe Programmierung. Hier spielt Sicherheit typischerweise eine große Rolle. Das stellt weitere besondere Anforderungen an die Sprache und ihre Entwickler. C++ ermöglicht es, all jene Techniken einzusetzen, die C bereits erlaubt. Dazu zählen auch solche, die Entwickler in sicherheitskritischen Systemen gar nicht oder nur mit großer Vorsicht einsetzen sollten. Zu nennen wären etwa Makros, Zeigermanipulationen, explizites Speichermanagement oder auch explizite Datenkonvertierungen über Casts.

Abbildung 1: Die C++ Core Guidelines warten auf Github und wollen über die Jahre angesammelte Erfolgsrezepte an Entwickler weitergeben.

Abbildung 1: Die C++ Core Guidelines warten auf Github und wollen über die Jahre angesammelte Erfolgsrezepte an Entwickler weitergeben.

Hier helfen dem Entwickler die C++-Regelwerke. Sie erklären, wie Software-Entwickler mit C++ sicher und effizient programmieren, ohne täglich im C++-Standard blättern oder mehr als 20 Jahre C++-Erfahrung auf dem Buckel haben zu müssen. Natürlich beantworten die Erfolgsrezepte nicht alle Fragen, der Entwickler muss sie im konkreten Anwendungsfall immer hinterfragen. Trotzdem geben sie ihm Regeln an die Hand, die es erlauben, bewährte Lösungen für seine Probleme zu finden. Damit landet der Artikel bei der anfänglichen Frage.

Mehrere Regelwerke

Die drei wohl bekanntesten Regelwerke sind das aus dem Jahr 2008 stammende Misra C++ [1], das deutlich modernere auf C++14 basierende Autosar C++ [2] sowie die C++ Core Guidelines [3], ein von der Community getragenes Regelwerk (Abbildung 1).

Misra C++

Die aktuellen Misra-C++-Richtlinien von 2008 hat die Motor Industry Software Reliability Association [4] formuliert. Sie lehnen sich an die Misra-C-Richtlinien [5] an, die bereits auf das Jahr 1998 zurückgehen. Ursprünglich von der Autoindustrie entwickelt, sind insbesondere die Misra-C-Richtlinien der Industriestandard beim Umsetzen sicherheitskritischer Software im Flugzeugbau, beim Militär und auch im Medizinbereich. Firmen müssen Software im sicherheitskritischen Bereich daher häufig gegen das Misra-Regelwerk zertifizieren.

Den Misra-C-Richtlinien folgend beschreiben die Misra-C++-Richtlinien eine sichere Teilmenge von C++. Diese besteht aus gut 200 Regeln, welche die Richtlinie als »document«, »required« oder »advisory« einordnet. Ist das Einhalten der Regeln in der Kategorie »document« ein Muss, handelt es sich bei den als »required« oder »advisory« klassifizierten um Soll-Regeln. Der feine Unterschied: Abweichungen bei den als »required« eingestuften Regeln müssen Entwickler formal beantragen, begründen und prüfen – was für die als »advisory« ausgewiesenen Regeln nicht gilt. Tabelle 1 zeigt ein paar Beispiele.

Tabelle 1

Einige der Misra-C++-Regeln

Kategorie

»required«

»advisory«

»document«

Unnötige Konstrukte

Projekt soll keinen toten Code und keine unbenutzten Variablen enthalten

Assembler-Deklaration

Jeden Assembler-Einsatz dokumentieren

Arithmetik

Fließkommazahlen-Arithmetik dokumentieren

Sprache

C++-03-Standard verwenden

Kommentare

Keine C-Kommentare verwenden

Keine auskommentierten Codebereiche

Zeiger-Konvertierung

»NULL« darf keine natürliche Zahl sein

Mehrere Basisklassen

Keine von einer virtuellen Basisklasse abgeleitete Klassen nutzen

Virtuelle Funktionen

Jede virtuelle Funktion, die eine virtuelle Funktion überschreibt, sollte das Schlüsselwort »virtual« verwenden

Ausnahmebehandlung

Ausnahmen nur für die Fehlerbehandlung verwenden

Templates

Alle teilweisen oder vollständigen Template-Spezialisierungen in der gleichen Datei wie das primäre (allgemeine) Template deklarieren

Makro-Ersetzungen

Den »#«- und »##«-Operator nicht verwenden

Bibliothek

Die C-Bibliothek nicht verwenden

Sämtlicher Bibliothekscode soll konform zu Misra C++ sein

Statische Code-Analyse-Werkzeuge helfen, diese und weitere Regeln zu verifizieren. Ein Wermutstropfen aber bleibt: Misra C++ basiert noch auf C++03. Das bedeutet, sicherheitskritische Software gegen ein Regelwerk zu zertifizieren, das dem Stand der Technik vor 15 Jahren entspricht. Seit dem Erscheinen von Misra C++ sind drei neue C++-Standards erschienen (Abbildung 2).

Abbildung 2: Seit Misra C++ erschienen ist, hat sich der C++-Standard deutlich weiterentwickelt.

Abbildung 2: Seit Misra C++ erschienen ist, hat sich der C++-Standard deutlich weiterentwickelt.

Das konzeptionelle Problem von Misra C++ besteht darin, dass das Standardisieren eines Regelwerks für eine relativ statische Programmiersprache wie C, wie sie Misra C versucht, erfolgreich sein kann. Bei der sehr dynamischen Programmiersprache C++ muss dieses Vorhaben hingegen langfristig scheitern.

Autosar C++

Anders als Misra C++ setzt Autosar C++ (die AUTomotive Open System ARchitecture) auf C++14. Auch Autosar regelt den Einsatz von C++ in sicherheitskritischen Systemen und versteht sich als Update für Misra C++. Die Macher haben viele Regeln von Misra C++ übernommen, eine Menge davon aber auch entschärft und überarbeitet. So sind mit Autosar Ausnahmen wie das Überladen von Operatoren und dynamisches Speichermanagement erlaubt. Interessant ist, welche Techniken Autosar verbietet:

  • »malloc()«, »free()« und C-Casts
  • »const_cast«, »dynamic_cast« und »reinterpret_cast«
  • »typedef«-Bezeichner
  • Unions
  • Mehrfachvererbungen
  • »friend«-Deklarationen
  • benutzerdefinierte Literale
  • dynamische Ausnahmespezifikationen (»throw«)

Diese Einschränkungen wirken schlüssig, lediglich das Verbot benutzerdefinierter Literale ist mir nicht einsichtig. Sie sind ein herausragendes Feature in sicherheitskritischen Systemen, denn sie erlauben das typsichere Rechnen mit Einheiten. Ihre Umsetzung basiert auf dem Überladen von Operatoren [6].

Autosar C++ beseitigt die größte Schwäche von Misra C++, da es auf modernem C++ basiert, muss sich aber mit den gleichen Herausforderungen wie Misra C++ auseinandersetzen: der formalen Standardisierung. Dieses konzeptionelle Problem gilt für die C++ Core Guidelines nicht.

Die C++ Core Guidelines

Hinter den C++ Core Guidelines steckt nicht die Automobilindustrie, sondern die C++-Community als treibende Kraft. Die Herausgeber sind Bjarne Stroustrup und Herb Sutter. Die Guidelines warten auf Github [7], jedes Mitglied der Community darf sie herunterladen und verbessern. Sie brauchen sich in Umfang und Verbindlichkeit nicht vor Misra und Autosar zu verstecken.

Die Regeln legen sehr viel Wert auf statische Typsicherheit und sicheres Ressourcenmanagement. Sie decken die Themen Schnittstellen, Funktionen, Klassen und Hierarchien, Ressourcenmanagement, Ausdrücke, Fehlerbehandlung, Konstanten, Templates, Parallelität und Standardbibliothek ab. Mit der Guidelines Support Library (GSL, [8]) gibt es zudem eine Bibliothek, die das Einhalten der Regeln prüft.

Zum Kern vorstoßen

So viel erst einmal zu den C++ Core Guidelines. Mit diesen ganz allgemein und den wichtigsten Regeln beschäftigen sich die nächsten Artikel. Denn die intensive Auseinandersetzung mit den Richtlinien hilft Entwicklern sehr dabei, C++ besser zu verstehen und sicherer und effektiver einzusetzen.

Der Autor

Rainer Grimm ist Trainer für C++ und Python. Seine zahlreichen C++-Bücher, zuletzt “The C++ Standard Library” und “Concurrency with modern C++”, sind bei O’Reilly und Leanpub erschienen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 3 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben