RAII und Exceptions



  • Werner_logoff schrieb:

    dv_ schrieb:

    Aber, was ist, wenn beim Freigeben eine Exception passiert? Bei komplexeren Freigabeprozeduren dürfte das schnell eine Möglichkeit sein. Also, was tun?

    .. einfach auch eine Exception werfen, aber nur, wenn std::uncaught_exception() false liefert (C++-Standard Kapitel 15.5.3 [except.uncaught]).

    std::uncaught_exception() halte ich für eine der sinnlosesten Funktionen von überhaupt, da sie nicht aussagekräftig ist.
    (EDIT: bitte unbedingt den hier geposteten gotw Artikel lesen, der erklärt sehr schön wieso)

    Davon abgesehen halte ich es für eine ziemlich fragwürdige Praktik, das Verhalten eines Destruktors davon abhängig zu machen, ob es "safe" ist, eine Exception zu werfen. Bzw. halte ich es überhaupt für fragwürdig, einen Dtor Exceptions werfen zu lassen.

    Es gibt allerdings drei IMO sinnvolle Möglichkeiten zu reagieren:

    1. die Exception ganz schlucken ohne irgendwas zu machen
    2. das Programm abbrechen
    3. den Fehler einem "Manager-Objekt" mitteilen

    Welche von diesen Möglichkeiten "ideal" ist, kommt natürlich auf das Programm am das man schreibt, bzw. genauer den Programmteil.

    Mit Möglichkeit (3) meine ich z.B.: Angenommen man hat ein Temp-File, das man aus irgendeinem Grund nicht löschen kann, und es ist irre wichtig dass das File doch irgendwann gelöscht wird. Dann kann man diesen Fehler einer Klasse mitteilen, die sich den Filenamen merkt, und dann vielleicht alle paar Sekunden versucht die "übriggebliebenen" Files zu löschen. Wenn es wichtig ist kann man die Filenamen auch irgendwo abspeichern (Datenbank), damit die Datei, falls das Programm beendet wird bevor die Datei nun endlich gelöscht werden konnte, bei einem späteren Programmstart gelöscht werden kann. Etwas in der Art.

    Etwas anderes ist IMO mit oder ohne Exceptions nicht wirklich sinnvoll. Oder will man Cleanup-Code abbrechen/unterbrechen, weil ein Teil des Cleanup nicht funktioniert hat? Dann wird ja der weitere Cleanup-Code der darauf folgt erst wieder übergangen.

    Falls es andere sinnvolle Möglichkeiten gibt, wäre ich daran interessiert, zu erfahren welche.

    p.S.: Fehler loggen ist natürlich auch gut. Würde ich zu Variante (3) rechnen.



  • ➡ Exceptions in c++ sind zu kompliziert



  • avrül schrieb:

    ➡ Exceptions in c++ sind zu kompliziert

    was hättest du denn gern einfacher?



  • wurde "zensiert"



  • avrül schrieb:

    wurde "zensiert"

    So wie ich die Moderatoren hier kenne, löschen die nicht wahllos Beiträge. Eine sachliche Begründung wäre wahrscheinlich kein Problem gewesen. Ich kann mir aber vorstellen, dass es sich um typisches C++-Bashing-Getrolle gehandelt hat, und in diesem Fall kann ich die Löschung unterstützen, sowas brauchen wir hier echt nicht.



  • hustbaer schrieb:

    avrül schrieb:

    ➡ Exceptions in c++ sind zu kompliziert

    was hättest du denn gern einfacher?

    Auf eine Art finde ich Exceptions gut, anderseits wurde imo nicht gut genug abgesteckt, wo sie gebraucht werden sollen. Da scheinen auch die Meinungen immer mal wieder recht auseinander zu gehen. Von dem her finde ich auch, dass Exceptions besser definiert hätten werden können.

    Nichts desto trotz empfinde ich sie als einen Segen im Gegensatz zu Fehler Rückgabewerte. 🙂



  • drakon schrieb:

    ...anderseits wurde imo nicht gut genug abgesteckt, wo sie gebraucht werden sollen. ...

    Nunja ... aber entspricht das nicht einfach dem gesamten Profil von C++?

    Eigentlich schreibt der Standard nie vor, wo man was verwenden sollte, sondern lediglich, wo man etwas nicht verwenden kann.
    Der Standard schreibt auch nicht vor, dass Destruktoren keine Exceptions durchlassen dürften, angeforderter dynamischer Speicher freigegeben werden muss, Variablennamen aussagekräftig sein müssen, ....

    Schon bei const gibt's mehr als eine Meinung, was "best practice" ist und bei Exceptions ist das halt nicht anders.
    Finde ich eigentlich besser als wenn "wohlüberlegte Ausnahmen" nicht mehr möglich wären.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    drakon schrieb:

    ...anderseits wurde imo nicht gut genug abgesteckt, wo sie gebraucht werden sollen. ...

    Nunja ... aber entspricht das nicht einfach dem gesamten Profil von C++?

    Eigentlich schreibt der Standard nie vor, wo man was verwenden sollte, sondern lediglich, wo man etwas nicht verwenden kann.
    Der Standard schreibt auch nicht vor, dass Destruktoren keine Exceptions durchlassen dürften, angeforderter dynamischer Speicher freigegeben werden muss, Variablennamen aussagekräftig sein müssen, ....

    Ich meinte nicht im Standard, sondern eher Allgemein. Das Thema Exceptions als allgemeines Konzept ist nicht so etabliert, wie andere Konstrukte in C++. Vor allem unterscheiden sie sich von innerhalb der Sprachen von Einsatzgebieten. Das ist imo das Problem. Z.B die Technik der Polymorhpie gibt es ja in sehr vielen Sprachen und da ist aber ziemlich genau bestimmt, wann und wo man es am ehesten einsetzt. Klar gibt es je nach dem Unterschiede, aber ein C# Programmierer ist nicht verwirrt, wenn er an gewissen Orten in C++ Code Polymorphie sieht. Bei Exceptions ist da allerdings anderst. Respektive der C# wird soch sehr oft in C++ Code fragen, warum da keine Exception geworfen wird, weil das in C# sonst so üblich wäre.

    Um kurz auf deine Beispiele einzugehen. OK, das mit den Exceptions und Destruktor lasse ich mal weg, aber das mit dem dynamischen Speicher ist doch in jeder Sprache so, oder? - Wenn man Speicher anfordert, dann muss man ihn wieder freigeben, ob das jetzt ein GC macht, oder man selbst ist vom Prinzip her ja egal. Variablennamen sollten aussagekräftig und verständlich sein. Das kann man auch praktisch in jeder Sprache so allgemein sagen.

    Aber wann eine Exception geworfen werden sollte kann imo nicht pauschal gesagt werden.



  • drakon schrieb:

    ...Ich meinte nicht im Standard, sondern eher Allgemein. ...

    Ach so.
    Hatte ich mißverstanden.

    drakon schrieb:

    ...Aber wann eine Exception geworfen werden sollte kann imo nicht pauschal gesagt werden.

    Das erlebe ich auch so: Es gibt keinen sprachübergreifenden Konsens.
    Nichteinmal innerhalb der Sprache (kenne jetzt aber nur C++ & Java) scheint es so 100%ig klar zu sein, wann man welche Exception wirft (und wann man mit Returncodes oder anderen Techniken arbeitet).
    Das ist IMHO aber nicht direkt ein Phänomen mit Exceptions, sondern spiegelt eher die unterschiedlichen Herangehensweisen an "Fehler-/Ausnahme-/...-Situationen" wider. In C gab's das Problem früher auch schon mit "Returncode vs. errno".

    Eins gibt's allerdings schon: "Exception fängt man nur da, wo man sie auch bearbeiten kann"...

    Gruß,

    Simon2.



  • drakon schrieb:

    Von dem her finde ich auch, dass Exceptions besser definiert hätten werden können.

    Sowas ist immer ein Risiko. Schau dir zB Java an, da haben die Verantwortlichen blödsinn definiert (checked exceptions) und nun muss man in Java damit leben. In C# dagegen wurde rein garnichts definiert und man lebt dort weitaus besser.

    Wenn du Verwendungszwecke und Features eng definierst riskierst du immer blödsinn zu definieren. ist also ein zweischneidiges schwert 😉



  • Das ist IMHO aber nicht direkt ein Phänomen mit Exceptions, sondern spiegelt eher die unterschiedlichen Herangehensweisen an "Fehler-/Ausnahme-/...-Situationen" wider. In C gab's das Problem früher auch schon mit "Returncode vs. errno".

    Hmm. Im Bezug auf C++ und sagen wir die "moderneren" Techniken finde ich, dass man da etwas verpasst hat.
    Stell dir vor es gäbe ein best-practise, wie für viele Sachen im Bezug auf Exceptions. Eine pauschalaussage, welche die meisten Fälle abdeckt. (is-a, vs. has-a in Vererbung, dynamische vs. automatische Objekte usw. gibt es das grundsätzlich und so ziemlich alle können diese Meinung vertreten, wann man diese Techniken braucht und wann eher nicht)

    Eins gibt's allerdings schon: "Exception fängt man nur da, wo man sie auch bearbeiten kann"...

    Jap, genau so etwas meine ich. Da wird kaum jemand kommen und sagen: hach, ich fang die auch da und da. Das passt einfach nicht und die Exceptions dort fangen, wo man sie behandeln kann ist wohl best-practise.

    Wenn du Verwendungszwecke und Features eng definierst riskierst du immer blödsinn zu definieren. ist also ein zweischneidiges schwert

    Wie gesagt meinte ich nicht, dass etwas vom Standard vorgeschrieben werden hätte sollen, sondern eher, dass es ein wohldefiniertes best-practise gibt, wie in sehr vielen anderen Techniken auch, wann sie eingesetzt werden und wann nicht. Da hat man imo etwas sehr mächtiges verpasst. Stell dir mal die Utopie vor, dass allen Programmierer klar und einleuchtend ist, wie man Fehler meldet und behandelt, wie auch allen klar ist, wann man Polymorphie einsetzt und wann nicht. 😉



  • Ich denke "Exceptional C++" (Herb Sutter) sollte einiges zu dem Thema enthalten.



  • hustbaer schrieb:

    Ich denke "Exceptional C++" (Herb Sutter) sollte einiges zu dem Thema enthalten.

    Was meinst du genau? - Das Buch enthält sehr viel, um mit Exceptions umzugehen und exceptionsicheren Code zu schreiben, aber IIRC wird da nichts oder nur sehr wenig dazu gesagt, wann es passend ist eine Exception zu werfen.


Anmelden zum Antworten