Kann / sollte ich std :: exception für die normale Fehlerbehandlung verwenden?

8

Ich werde dieses neue Projekt in C ++ starten und über eine schmerzlose Art der Fehlerbehandlung nachdenken. Jetzt werde ich nicht anfangen, Ausnahmen zu werfen und abzufangen, und werde wahrscheinlich überhaupt keine Ausnahmen werfen, aber ich dachte - sogar für die normale Fehlerbehandlung, warum rolle ich meine / copy-paste eine Klasse zur Beschreibung von Fehlern / status, wenn ich einfach std::exception und seine Kindklassen (oder vielleicht std::optional<std::exception> ) benutzen könnte?

%Vor%

Arbeitet irgendjemand / jedes Projekt auf diese Weise? Ist es eine lächerliche Idee oder nur ein bisschen knarren?

    
einpoklum 28.04.2015, 21:28
quelle

3 Antworten

3

Ich denke nicht, dass Sie Ausnahmen konstruieren sollten, wenn Sie nicht wirklich beabsichtigen, sie zu werfen. Ich würde einen Bool- oder Enum-Rückgabetyp empfehlen. Die Absicht wird für jemanden klarer, der Ihren Code liest, und sie werden schneller sein. Wenn Sie jedoch eine Exception konstruieren, kommt jemand anderes und denkt, dass sie die Ausnahme auslösen und das ganze System zum Absturz bringen kann.

C ++ - Ausnahmen spielen eine wichtige Rolle in der Ressourcenverwaltung, lösen Destruktoren und all das aus (RAII). Sie auf andere Weise zu benutzen, wird der Performance schaden und (was noch wichtiger ist) die heilige Hölle von jemandem verwirren, der versucht, den Code später zu pflegen.

Sie können jedoch mit einer Statusberichtsklasse, die NICHT mit std :: exception zu tun hat, das tun, was Sie wollen. Menschen tun viel zu viel für "schneller" Code, wenn sie es nicht müssen. Wenn eine Statusaufzählung nicht gut genug ist und Sie weitere Informationen zurückgeben müssen, funktioniert eine Statusberichterstattungsklasse. Wenn es den Code leichter lesbar macht, dann gehen Sie darauf.

Nennen Sie es nicht eine Ausnahme, es sei denn, Sie werfen es tatsächlich.

    
Kenny Ostrom 30.04.2015 13:55
quelle
2

Ich denke, dass Leistung allein problematisch sein könnte. Betrachten Sie den folgenden Code:

%Vor%

Auf meinem CentOS, mit gcc 4.7, wurde bei:

getaktet %Vor%

in den Vanilla-Einstellungen und:

%Vor%

bei -O2-Einstellungen.

P.S. Ich persönlich würde Exceptions / Stack-Unwinding verwenden, weil ich glaube, dass es ein grundlegender Teil von C + ist, möglicherweise wie @vsoftco oben gesagt hat.

    
Ami Tavory 30.04.2015 13:24
quelle
0

Um Ihre Frage zu beantworten, ist dies keine lächerliche Idee und Sie können tatsächlich std::exception für die regelmäßige Fehlerbehandlung verwenden; mit einigen Vorbehalten.

Verwenden von std::exception als Ergebnis der Funktion

Nehmen wir an, eine Funktion kann in mehreren Fehlerzuständen enden:

%Vor%

Wie können Sie das mit einem std::exception oder einem optionalen umgehen? Wenn die Funktion zurückkehrt, wird eine Kopie der Ausnahme erstellt, wobei nur der std::exception -Teil beibehalten und die Einzelheiten des tatsächlichen Fehlers weggelassen werden; Sie mit der einzigen Information verlassen, dass "yep, etwas schief gelaufen ist ...". Das Verhalten entspricht dem Zurückgeben eines booleschen Werts oder eines optionalen Werts des erwarteten Ergebnistyps (falls vorhanden).

Verwenden von std::exception_ptr zum Speichern der Details

Eine andere Lösung wäre, denselben Ansatz wie in std :: promise anzuwenden ist ein std::exception_ptr zurückzugeben. Dort können Sie entweder nichts oder eine Ausnahme zurückgeben, während Sie die tatsächlichen Fehlerdetails beibehalten. Das Wiederherstellen der tatsächlichen Art des Fehlers kann immer noch schwierig sein.

Zurückgeben des Fehlers oder des Ergebnisses im selben Objekt

Eine weitere Option wäre die Verwendung des Expected<T> Vorschlags und seine Implementierung . Dort können Sie den Wert oder den Fehler in einem einzelnen Objekt zurückgeben und den Fehler behandeln, den Sie wünschen (durch Testen des Fehlers oder mit der regulären Ausnahmebehandlung), mit einigen Besonderheiten für den Fall, dass eine Funktion keinen Wert zurückgibt (mehr auf Stack Overflow oder auf dieser Blog ).

So wählen Sie

aus

Meine persönliche Meinung zu diesem Thema ist, dass Sie, wenn Sie Ausnahmen verwenden, diese dann so verwenden, wie sie entworfen wurden, eventuell mit zusätzlichen Tools wie Expected<T> , um es einfacher zu machen. Andernfalls, wenn Sie die standardmäßige Ausnahmebehandlung nicht verwenden können, sollten Sie sich für eine Lösung entscheiden, die sich bewährt hat, wie das klassische Fehlercodesystem.

    
Julien 06.05.2015 20:15
quelle