std::exception und die Kinder



  • Find ich nicht. Wenn der Benutzer mir eine malformed XML-Datei eingibt, fliegt dadurch eine Exception, die fange ich und weiß dadurch, dass sie korrupt ist. Dann kriegt der Benutzer eine entsprechende Meldung und das Programm läuft weiter, als hätte man die Datei noch nicht geladen.

    Wieso soll ich da einen großartigen XML-Check vorsetzen? Regel ist, dass die XML-Datei in Ordnung ist. Ausnahme, dass etwas daran kaputt ist, weil der Benutzer Fehler gemacht hat.

    Es ist einfach unnötiger Aufwand irgendwelche Checks drumherum einzubauen, wenn der Parser das selbst macht und mir das mit einer Exception mitteilt. Mehr Code, der fehlerhaft sein kann und der einfach unnötig ist. Genau so sehe ich nicht, wieso ich bei einer Wurzelfunktion nicht einfach die Exception fangen kann, dem Benutzer die Ausgabe gebe, dass das Argument invalide ist und der Ablauf weitergeht... Wo ist das Problem?



  • @Eisflamme
    Einen "logic error" mit einer Exception statt ASSERT/abort/... zu behandeln kann oft in Interfaces zwischen zwei Programmteilen Sinn machen.

    Denk nur mal an Betriebssysteme.

    Ich denke die wenigsten Leute hätten viel Freude damit wenn das OS sämtliche "logic errors" mit einem BSOD bzw. auch nur dem Abbruch des Prozesses quittieren würde.
    Beispielsweise wenn man einen IOCTL an ein Gerät schickt das diesen gar nicht unterstützt.
    Oder wenn man versucht in ein File zu schreiben das man nicht schreiben darf.

    Das sind Dinge die ein Programm immer vermeiden könnte, aber oft ist es besser es einfach zu probieren und dann zu sehen was passiert. Weil es oft viel unkomplizierter umzusetzen ist, und unkomplizierter ist besser als komplizierter.

    Natürlich kann man jetzt sagen dass alles was "von ausserhalb" kommt erstmal validiert werden müsste. Aber es ist oft einfach nicht praktikabel alles vorab erstmal zu validieren. Es ist oft viel praktischer in der Schicht die die Requests von Ausserhalb entgegennimmt nur bestimmte grundlegende Dinge zu validieren, und den Request dann an einen anderen Programmteil weiterzureichen.
    Wenn der dann aber sämtliche "invalid argument" Fehler mit ASSERT/abort quittiert, hat man ein Problem.

    mMn. muss man in jedem Fall einzeln entscheiden ob es OK ist bei einem bestimmten Fehler eine Exception zu werfen, oder ob es doch besser wäre den Prozess einfach abzubrechen.



  • Wieso soll ich da einen großartigen XML-Check vorsetzen? Regel ist, dass die XML-Datei in Ordnung ist. Ausnahme, dass etwas daran kaputt ist, weil der Benutzer Fehler gemacht hat ... wenn der Parser das selbst macht und mir das mit einer Exception mitteilt

    Nein, Exceptions werden normalerweise nicht fuer diese Art Ausnahmen benutzt. Normalerweise gibt der Parser den Fehler beim Parsen nicht durch eine Exception nach aussen weiter. Bedenke: C++ ist nicht Java, wo dass vielleicht ueblich ist. Exceptions werden fuer unvorhersehbare Dinge benutzt und nicht fuer den Kontrollfluss. Beispiel Netzwerkverbinding: Eine Ausnahmesituation ist, wenn eine bestehende Netzwerkverbindung waehrend einer Transaktion gekappt wird indem der Netzstecker gezogen wird. Selbst dann muss nicht auf Exceptions zurueckgegriffen werden.

    Beispiel fuer logic_error: Dynamische Datentyp, der sowohl Strings und Zahlen repraesentieren kann. Operationen auf diesen bspw. + sind nur partiell definiert.



  • hustbaer:
    Okay, verstehe ich!

    knivil:
    Das verstehe ich auch, wobei ich es immer noch schwierig finde die Grenze zu ziehen. Unvorhergesehen ist ja im Grunde nichts, wenn man dafür eine Exception bastelt, denn dann hat man ja dran gedacht. Dein Beispiel für logic_error finde ich gut. 👍 Hm, aber für mich ist ein Ausnahmefall auch nur ein anderer Zweig eines Kontrollflusses. Wie gesagt: Meine XML-Datei wird ja eigentlich immer korrekt geparst. Dass die invalide ist, ist für mich unvorhergesehen (zu einem gewissen Maße, siehe Satz 2).

    Auch glaube ich dann bei vielen Bibliotheken Konflikte zu sehen. Also RapidXML schmeiß eben in dem Szenario eine Exception, ist das dann "falsch"? Und bei std::cin kann man bei Bedarf auf fehlerhafte Benutzereingabe eine Exception werfen lassen, das ist für mich aber auf derselben Ebene wie eine XML-Datei-Eingabe: wenn der Benutzer bei einer Zahlenerwartung einen String eingibt, ist das für mich genau so Kontrollfluss (oder Ausnahme, je nach Standpunkt) wie bei einer malformed XML-Datei. Dann wäre hier eine Exception ja auch nicht angebracht?



  • ist das dann "falsch"?

    Sicher nicht. Finde ich es gut: Nein. 🙂 Klar kann man sagen, ist Geschmackssache. Aber manche haben halt einen schlechten Geschmack. 🙂 Wer definiert guten Geschmack? Hmm, die C++-Community wahrscheinlich.

    Unterschied zwischen Benutzereingabe und XML-Datei: Benutzer verschreibt sich viel oefter als dass eine maschinengenerierte XML-Datei fehlerhaft ist. Deswegen ist es legitim, auf Fehler unterschiedlich zu reagieren.

    Auch glaube ich dann bei vielen Bibliotheken Konflikte zu sehen

    Nun, viele Bibliotheken schmecken eben nicht gut. Aber nicht immer kann man sich ein Gericht von einem 3-Sterne-Koch leisten.



  • Ja, nur manchmal kann der Benutzer auch manuell die XML-Datei ändern. Wollen die meisten bei mir nicht, aber kommt vor. Aber gut, ich sehe schon, die Grenze ist verschwommen.

    Macht das boost für Deinen Geschmack gut? Irgendworan muss man sich ja ein Beispiel nehmen.



  • In erster Linie kann man sich ein Beispiel an der Standardbibliothek nehmen. Wobei fuer meinen Geschmack die Funktionen fuer IO (Streams) und Iteratoren nicht mehr ganz zeitgemaess sind. Zu boost moechte ich mich nicht aeussern. 🙂



  • Ich denke mit std::optional kann man diese Fallunterscheidung ziemlich gut treffen. Tritt ein fehler in einer Funktion auf, gibt man eben nullopt zurück. Der Caller kann dann entscheiden, ob er den Fehler erwartet oder nicht. (explizit prüfen, oder den Wert einfach holen und die Exception fangen.)


Anmelden zum Antworten