Wozu exception handling?
-
Ich habe den Eindruck, dass dir der primäre Sinn von Exceptions nicht klar ist. Exceptions ermöglichen es, die Fehlerbehandlung an eine Stelle auszulagern, die die Kompetenz hat, mit dem Fehler umzugehen.
Beispiel new: Das new ist eine low-level Operation, die schiefgehen kann, die von Benutzercode aufgerufen wird. Oftmals mit sehr, sehr vielen Schichten Nutzercode um das new herum. Wenn das new schiefgeht, wie soll das new wissen, was die richtige Reaktion ist? Es weiß schließlich nicht, in welcher Art von Programm es sich befindet. Darum schmeißt es eine Exception. Die propagiert dann so lange weiter, bis eine Stelle entscheiden kann, ob ein bad_alloc für diese Programm ein schwerwiegender Ausnahmefehler ist oder bloß eine Unannehmlichkeit. Soll das Programm noch irgendetwas sichern? Abstürzen? Ignorieren? All das kann das new nicht wissen, das ist Sache des Anwendungscodes, der weiß, was überhaupt die Anwendung ist.
Damit das funktioniert, braucht der Anwendungscode natürlich Garantien darüber, was der benutzte Code im Falle einer Exception macht. Wenn eine Exception tief im Code ohnehin UB in den Zwischenschichten auslöst, kann der Anwendungscode auch nichts mehr machen, da der gesamte Programmzustand undefiniert ist. Oder er kann wissen, dass der Zwischencode schon selber die Exceptions behandelt und gar nichts mehr werfen kann (der Zwischencode ist dann selber der Anwendungscode aus Sicht der Funktion, die die Exception geworfen hat). Oder er kann wissen, dass das Programm in einem zwar fehlgeschlagenen, aber definierten Zustand ist und somit weitere Aktionen möglich sind und welche.
Allgemein was Cleanup-Code und somit den Sinn von finally/RAII angeht: Es gibt auch andere Arten von Ressourcen als vom Betriebssystem verwalteten virtuellen Speicher. So manche davon müssen tatsächlich explizit von einem Programm freigegeben werden, da sie sonst auch nach Beenden des Programms noch belegt wären. Ein Beispiel für so etwas wäre eine Kommunikationsverbindung zu einem Server. Wenn man niemals "auflegt", dann denkt der Server bloß, man schicke gerade keine Daten, anstatt dass der Kommunikationspartner gar nicht mehr existiert.
edit: Oh, zwei gleichlautende Antworten in der Zeit, wo ich dies schrieb. War zu erwarten, bei so viel Text :p . Dafür gibt's als Bonus diesen Link, falls er noch nicht bekannt sein sollte, wo ein weiteres Mal die gleichen Erklärungen drin stehen:
http://www.c-plusplus.net/forum/219864
-
Ich muss auch sagen dass Exeptions sehr hilfreich sein können aber auf der anderen Seite auch eine Menge an Arbeit erzeugen und hin und wieder fühlt man sich sogar genötigt, recht unschönen Code zu schreiben damit das ganze Exeption save ist. Manchmal frage ich mich auch, ob es das wert ist.
-
TNA schrieb:
Ich muss auch sagen dass Exeptions sehr hilfreich sein können aber auf der anderen Seite auch eine Menge an Arbeit erzeugen und hin und wieder fühlt man sich sogar genötigt, recht unschönen Code zu schreiben damit das ganze Exeption save ist. Manchmal frage ich mich auch, ob es das wert ist.
Wenn du durch Exceptions bereits viel Arbeit und unschönen Code erzeugst, wie sähe denn erst dann der gleiche Code mit klassischen Fehlercodes aus?
-
Mein Eindruck ist, dass Ausnahme-sicherer Code in der Regel kürzer ist als welcher, der nicht sicher ist.
Und im Gegensatz zu Java oder C# sieht man in C++ fast nie eintry
, weil es den Destruktor gibt. Da der Destruktor auch ohne Ausnahmen ein unbezahlbares Hilfsmittel gegen Lecks aller Art ist, sollte man ihn unbedingt benutzen. Mit etwas Sachverstand bekommt man dann Ausnahmesicherheit kostenlos dazu.
Ausnahmen sind das sinnvollste Mittel zur Fehlerbehandlung in C++. Rückgabewerte wie in C sind viel zu umständlich und fehleranfällig. Schaut euch mal gute C-Programme an, die viele Ressourcen verwalten. Da entfällt schnell mal die Hälfte aller Statements auf Fehlerbehandlung.
-
TyRoXx schrieb:
Mein Eindruck ist, dass Ausnahme-sicherer Code in der Regel kürzer ist als welcher, der nicht sicher ist.
foo(std::unique_ptr<IrgendEineKlasse>(new IrgendEineKlasse))
ist nunmal länger als
foo(new IrgendEineKlasse);
-
Marthog schrieb:
TyRoXx schrieb:
Mein Eindruck ist, dass Ausnahme-sicherer Code in der Regel kürzer ist als welcher, der nicht sicher ist.
foo(std::unique_ptr<IrgendEineKlasse>(new IrgendEineKlasse))
ist nunmal länger als
foo(new IrgendEineKlasse);
Das ist kein Java. Die Leute wissen, dass es in C++
delete
gibt.
Da wird also noch an mindestens einer Stelle so ein Müll stehen wie:if (p) { delete p; p = NULL; }
Sogar eher an mehreren Stellen pro
new
.
Das ist dann deutlich länger als richtiges C++.Außerdem ist die Länge eines einzigen Ausdrucks nicht so entscheidend. Ich meinte eher die Länge von Funktionen bzw die Anzahl der Statements.
-
Abgesehen davon:
Marthog schrieb:
foo(std::unique_ptr<IrgendEineKlasse>(new IrgendEineKlasse))
Ist nicht exception-safe...
Edit: Ok, in dem konkreten Beispiel isses in der Regel wohl ok.
foo(std::unique_ptr<IrgendEineKlasse>(new IrgendEineKlasse), std::unique_ptr<IrgendEineAndereKlasse>(new IrgendEineAndereKlasse))
wär aber schon nimmer ok...
-
Marthog schrieb:
foo(std::unique_ptr<IrgendEineKlasse>(new IrgendEineKlasse))
Darum wird C++14 auch
std::make_unique()
haben.foo(std::make_unique<IrgendEineKlasse>())
Ist exceptionsicher, vermeidet die doppelte Benennung des Typen und bringt
new
endgültig aus dem Anwendercode.
-
nwp3 schrieb:
Anders ausgedrückt: Wenn in einer Ausnahmesituation ein Resourcenleck entsteht ist das völlig in Ordnung. Wenn diese Situation so häufig vorkommt, dass die Resourcen knapp werden, dann war das keine Ausnahmesituation und Exceptions wurden falsch benutzt und (...)
Falsch.
Begründung: z.B. das was audacia geschrieben hat. Bzw. wenn du 1-2 Minuten googelst wirst du "Milliarden und Abermilliarden" von Diskussionen zu dem Thema finden, wo die ganzen alten Argumente durchgekaut werden.Bzw. warum Exceptions genau nicht nur für das da sind was du beschreibst, beantwortest du dir ja selbst, indem du feststellst dass sie dann sinnlos wären.
Exception != Fatal-Error. Exception = Ausnahmesituation. Ausnahmesituation = nicht der Regelfall. Nicht der Regelfall != kommt nie vor. Case closed.
-
chaos7568568 schrieb:
ihr HU*ENSO*HNE!!!
was zum geier bedeutet UB!!!
Unter-belichted
-
Undefined Behaviour - Der Standard lässt offen, was dann passiert und die konkrete Implementierung darf selber entscheiden. Oft wird dabei nach Geschwindigkeit entschieden und UB ist in vielen Fällen zu meiden, weil es sein kann, dass alles funktioniert, aber in 10 Jahren und auf einem anderen Betriebssystem irgendwo ein kleiner Fehler auftritt, der alles zum Zusammenbrechen bringt.