C++ Exceptions in der Praxis
-
Genau sowas theoretisches will ich nicht. Ich will praktische Beispiele. Wo hast du zum letzen mal eine Exception verwendet?
Du verwechselst Theoretisch <=> Praktisch mit Abstrakt <=> Konkret. Was Exception00 schrieb war eine abstrakte Beschreibung der Situationen in denen Exceptions Anwendungen finden. Soll man dir jetzt alle Situationen aufzählen, in der Exception000 Bedingung zutrifft? Google verdammt nochmal!
-
Neulich hatte ich folgende Situation (ein Bsp.):
class Options { public: void add(const std::string& name, const std::string& value); // throw(InvalidArgument) }; class WebServer { public: WebServer(); bool isStarted() const; void start(const Options& options); // throw(InvalidOperation) void stop(); // throw(InvalidOperation) };Dabei wäre es natürlich schön WebServer::start(..) im Konstruktor und WebServer::stop() im Destruktor aufzurufen (start / stop dortin verschieben) - jedoch ist das aus technischen Gründen nicht möglich.
WebServer::start(..) darf nur aufgerufen werden, wenn WebServer::isStarted() false zurückgibt. Umgekehrt darf WebServer::stop(..) nur aufgerufen werden wenn WebServer::isStarted() true zurückgibt. In Fällen wo diese Bedingungen verletzt sind werfe ich eine Exception.
Bei Options::add(..) wird eine InvalidArgument Exception geworfen, wenn die Option nicht existiert (der WebServer weiss nichts damit anzufangen).
Simon
-
Praktiker schrieb:
Exception000 schrieb:
Für nicht planmäßig im Programm auftretende Ausnahmen

Wenn ich eigentlich erwarte, dass es funktioniert, aber nicht zwangsläufig
funktionieren muss.Jetzt frag nicht, was eigentlich funktionieren muss...
Genau sowas theoretisches will ich nicht. Ich will praktische Beispiele. Wo hast du zum letzen mal eine Exception verwendet?
Auf Anhieb fallen mir Folgende ein:
-
Fehler bei Hardwarezugriffen-Zugriffen
-
Datei-Zugriffen
-
Socket
-
...
-
Unerfüllte Preconditions (siehe theta) [EDIT: wobei ich diese manchmal nur für im Debug schmeisse]
-
auch: bestimmte Resource nicht verfügbar
-
Falls übergebene Parameter nicht den Anforderungen entsprechen
-
Invalider/Nichtparsebarer Content (z. B. invalides Xml)
-
Unbekannte Bezeichner (Attribut "xyz" kann nicht verarbeitet werden)
-
Ungültige Kombination von Parametern (wenn x dann kann nicht auch y)
-
Unterbrechen von Threads
Gruß,
XSpille
-
-
Werft ihr bei ungültigen Argumenten Exceptions? Ich würde da ein assert einbauen, im Release sollte sowas ja nicht mehr vorkommen.
-
assert schrieb:
Werft ihr bei ungültigen Argumenten Exceptions? Ich würde da ein assert einbauen, im Release sollte sowas ja nicht mehr vorkommen.
Kommt draus an, wo sie herkommen...
Wenn sie aus z. B. Konfigurationsdateien kommen, dann kann es auch im
Release passieren.
-
assert schrieb:
Werft ihr bei ungültigen Argumenten Exceptions? Ich würde da ein assert einbauen, im Release sollte sowas ja nicht mehr vorkommen.
Ich würde sagen, das kommt daraufan von wo die Argumente kommen.
-
assert schrieb:
Werft ihr bei ungültigen Argumenten Exceptions? Ich würde da ein assert einbauen, im Release sollte sowas ja nicht mehr vorkommen.
Assert ist für Programmierfehler in deinem eigenen Code. Aber nicht für aufrufenden Code.
Es gibt drei Fehlerkategorien:
1. Logikfehler, die der Aufrufer zu verantworten hat (z.B. falsche Parameter übergeben). => std::logic_error
2. Laufzeitfehler, die der Aufrufer und der eigene Code nicht zu verantworten haben (z.B. Server ist auf einmal nicht erreichbar). => std::runtime_error
3. Programmierfehler, wofür nur ich selber für verantwortlich bin und meinen eigenen Code damit prüfe. => Assert
-
Artchi schrieb:
Assert ist für Programmierfehler in deinem eigenen Code. Aber nicht für aufrufenden Code.
Doch, natürlich soll
assertauch falsche Benutzung der Schnittstellen verhindern. Also Logikfehler wievector[invalidIndex]oderemptyVector.pop_back().Die Exception
std::logic_errormacht normalerweise keinen Sinn. Denn sie führt nur dazu, das Programm nach einem Logikfehler weiterlaufen zu lassen. Aber nach einem Logikfehler funktioniert das Programm nicht mehr zuverlässig, es hätte gar nie soweit kommen dürfen. Ich kann mir zwar Ausnahmen wie die Freigabe kritischer Ressourcen vorstellen, aber generell sollte man für Logikfehlerasserteinsetzen. Dann wird man auch unmittelbar auf den Fehler aufmerksam gemacht und hat keinen Overhead im Release-Modus.Grundsätzlich kann man sagen, dass Exceptions für Fälle konzipiert sind, die auch bei korrekt geschriebenem Code eintreten. Also unvorhersehbare Laufzeitfehler.
-
Nexus schrieb:
Grundsätzlich kann man sagen, dass Exceptions für Fälle konzipiert sind, die auch bei korrekt geschriebenem Code eintreten.
I agree

Nexus schrieb:
Also unvorhersehbare Laufzeitfehler.
Meinst du diese Aussage stimmt auch, wenn man die Unterbrechungspunkte in
boost mit der boost::thread_interrupted berücksichtigt?
Ich glaube in dem Fall sind sie (häufig) vorhersehbar.
-
Exceptions machen imo besonders in der Systemprogrammierung Sinn.
Es gibt in etwa 1 Millionen Gründe warum ein Systemaufruf fehlschlagen kann, in der Regel funktioniert er allerdings.