Blog 5 Min. Lesezeit

Verwenden oder nicht verwenden: Die Debatte um C++-Ausnahmen

Diesen Artikel teilen
To Use or Not To Use: C++ Exceptions Debate

Vor mehr als 20 Jahren wurde die Ausnahmebehandlung in C++ eingeführt. Nach vielen Jahren praktischer Erfahrung verfügen wir heute über wertvolles Feedback zu ihren Vor- und Nachteilen.

Sehen wir uns die Meinungen einiger prominenter Persönlichkeiten der C++-Community an und wie sie zur Verwendung von Exceptions stehen.

I – C++-Experten

Herb Sutter, aus seinem Artikel:

Zusammenfassung: Bevorzugen Sie Exceptions gegenüber Fehlercodes, um Fehler zu melden. Verwenden Sie Statuscodes wie Rückgabecodes oder errno nur dann für Fehler, wenn Exceptions nicht eingesetzt werden können, sowie für Zustände, die keine Fehler sind. Wenn eine Wiederherstellung nicht erforderlich oder unmöglich ist, verwenden Sie andere Verfahren wie eine geordnete oder unmittelbare Beendigung.

Bjarne Stroustrup, aus seiner FAQ-Seite:

Was bringen mir Exceptions? Kurz gesagt: Fehlerbehandlung mit Exceptions macht Code einfacher, sauberer und verringert die Wahrscheinlichkeit, Fehler zu übersehen. Bei klassischen errno- und if-Konstruktionen sind Fehlerbehandlung und normaler Programmablauf eng miteinander verflochten. Dadurch wird der Code unübersichtlich und es ist schwer sicherzustellen, dass alle Fehlerfälle behandelt wurden.

Scott Meyers, aus seinem Buch „Effective C++“:

Vor vierzig Jahren galt Code voller goto-Anweisungen als völlig akzeptabel. Heute streben wir strukturierte Kontrollflüsse an. Vor zwanzig Jahren galten global zugängliche Daten als gute Praxis; heute kapseln wir Daten. Vor zehn Jahren schrieb man Funktionen, ohne über die Auswirkungen von Exceptions nachzudenken; heute streben wir exception-sicheren Code an.

Joel Spolsky, aus seinem Artikel:

Ich wurde gefragt, warum ich nicht gern mit Exceptions programmiere. Sowohl in Java als auch in C++ lautet meine Regel:

1 – Niemals selbst eine Exception werfen. 2 – Jede mögliche Exception einer verwendeten Bibliothek unmittelbar dort abfangen und sofort behandeln.

Andrei Alexandrescu, aus seinem Artikel

Exception-sicheren Code zu schreiben ist schwierig

Später im selben Artikel erklärt er, wie sich der Umgang mit Exceptions mithilfe des Scope-Guard-Idioms vereinfachen lässt:

ScopeGuard verallgemeinert eine typische Implementierung des C++-Idioms „Resource Acquisition Is Initialization“. Der Unterschied besteht darin, dass ScopeGuard sich ausschließlich um das Aufräumen kümmert: Sie erwerben die Ressource, ScopeGuard sorgt für ihre Freigabe.

Jon Kalb, von seiner Website

Die sichere Verwendung von Exceptions ist ein nicht triviales Problem, mit dem sich die Branche seit fast zwei Jahrzehnten beschäftigt. Wer Zweifel an Exception Safety hat oder Best Practices für Exceptions in C++ kennenlernen möchte, sollte zunächst das zu lösende Problem und mögliche Alternativen betrachten. Danach lassen sich die Herausforderungen, typische Fehlversuche und Richtlinien für eine sichere Nutzung einschließlich der Migration von Legacy-Code behandeln.

II – Reale Projekte

Aus dem Boost Style Guide:

Wann sollte ich Exceptions verwenden?

Die einfache Antwort lautet: „Wann immer die semantischen und Performance-Eigenschaften von Exceptions angemessen sind.“

Aus dem Google Style Guide

Auf den ersten Blick überwiegen die Vorteile von Exceptions ihre Kosten, besonders in neuen Projekten. In bestehendem Code wirkt sich ihre Einführung jedoch auf sämtlichen abhängigen Code aus. Können Exceptions über die Grenzen eines neuen Projekts hinaus propagiert werden, wird auch die Integration in bestehenden exception-freien Code problematisch. Da ein Großteil des vorhandenen C++-Codes bei Google nicht auf Exceptions vorbereitet ist, ist die Einführung neuen Codes, der Exceptions erzeugt, vergleichsweise schwierig.

Clang

Das Clang-Team entschied sich gegen C++-Exceptions. Hier ein Zitat aus seinem Coding Standard:

Um Code- und Binärgröße zu reduzieren, verwendet LLVM weder RTTI (z. B. dynamic_cast<>) noch Exceptions. Diese beiden Sprachfeatures verletzen das allgemeine C++-Prinzip „you only pay for what you use“, da sie die ausführbare Datei selbst dann vergrößern können, wenn Exceptions oder RTTI nicht verwendet werden. Deshalb werden sie global deaktiviert.

LibreOffice hingegen verwendet C++-Exceptions.

Bei vielen bekannten Open-Source-C++-Projekten ist keine eindeutige Präferenz erkennbar: Beide Ansätze sind weit verbreitet.

III – C++-Community

Betrachtet man Foren, Artikel und Diskussionen in sozialen Medien, lassen sich innerhalb der C++-Community drei Hauptpositionen erkennen:

  • Verwenden – sie sind der beste Weg, außergewöhnliche Situationen zu behandeln.
  • Verwenden, aber mit großer Vorsicht – sie haben Nebenwirkungen.
  • Niemals verwenden.

Als C++-Entwickler kann man leicht verunsichert sein: Sollte man sie nun verwenden oder nicht?

Ein zentrales Problem wird von all diesen C++-Experten angesprochen: Exception-sicheren Code zu schreiben ist nicht trivial. C++-Entwickler lassen sich grob in vier Kategorien einteilen:

Kategorie 1: Verwenden C++-Exceptions, ohne auf Exception Safety zu achten.

Kategorie 2: Verwenden C++-Exceptions und kennen die Probleme rund um Exception Safety.

Kategorie 3: Verwenden keine Exceptions, verstehen deren Vor- und Nachteile aber nicht vollständig.

Kategorie 4: Verwenden keine Exceptions, weil sie deren Nachteile vollständig verstehen.

Entwickler der Kategorien 2 und 4 wissen genau, was sie tun. In den Kategorien 1 und 3 wird der Exception-Mechanismus dagegen nicht vollständig verstanden, was die Codequalität beeinträchtigen kann. Vielleicht ist die Frage „Exceptions verwenden oder nicht?“ also falsch gestellt. Entscheidend ist, ihre Vor- und Nachteile zu verstehen und anhand der eigenen Rahmenbedingungen eine bewusste Entscheidung zu treffen. Beide Ansätze können legitim sein.

Diesen Artikel teilen