Memberfunktion im Destruktor aufrufen, die eine Exception werfen kann



  • otze schrieb:

    assert im dtor sollte eigentlich zu undefiniertem verhalten führen oder?
    was passiert eigentlich, wenn man 2 objekte a und b hat, das erste wirft einen assert, damit wird das 2. objekt gekickt, welches wieder einen assert macht, wird der 2. aufruf dann ignoriert, oder bekommt man ein programm, welches im chaos untergeht?

    Du redest wirr. asserts werden nicht "geworfen" und haben auch kein undefiniertes Verhalten. Das Programm bricht einfach über die abort-Funktion ab. Das ist zwar oft unerwünscht, aber immer noch streng definiert. Kann es sein, dass du assert und Exceptions durcheinanderwirfst?

    monitor: Was meinst du mit "die eine Exception werfen könnte"? Tut sie oder nicht? Hier gilt eigentlich das gleiche wie immer mit assert: Wenn das Werfen einer Exception logisch gesehen nicht vorkommen kann (weil z.B. die Funktionsargumente so gewählt werden, dass die Funktion garantiert nicht wirft), dann ein assert. Wenn nicht vorhersehbare Einflüsse zur Laufzeit eine Exception erzeugen können, dann musst du dir was anderes einfallen lassen.



  • Also ich habe eine File-Klasse die die entsprechenden WinAPI Funktionen wrappt.

    Dort gibt es dann eine Memberfunktion close().

    void close()
    {
        if(fileHandle != INVALID_HANDLE_VALUE)
        {
            if(::CloseHandle(fileHandle) == 0)
            {
                throw FileException(...);
            }
    
            fileHandle = INVALID_HANDLE_VALUE;
        }
    }
    

    Diese könnte also theoretisch eine Exception werfen. Auch wenn das ganz schön unwahrscheinlich ist.



  • Wie würdest ihr das also in diesem Fall machen?



  • Ich hab so einen Fall und habe aus purer Verzweiflung

    try
    {
        foobar();
    }
    catch (...)
    {
    }
    

    genommen...



  • Diese könnte also theoretisch eine Exception werfen. Auch wenn das ganz schön unwahrscheinlich ist.

    Hier wür ich dir raten den return Wert von CloseHandle einfach zu ignoriren, oder ein assert drum zu bauen. CloseHandle ist ein Destruktor und wenn nicht mal der Destruktor in der Lage ist eine Klasse zu zerstören, wer dann? Eine Exception hat hier keinen Wert da du eh nur 2 Optionen hast : ignoriren oder Program beenden.

    Desweitern sollte es mich wundern wenn CloseHandle bei einem gültigen Handle einen Fehlerwert zurückgibt. (einzige Situation die ich mir vorstellen kann wäre wenn jemand die FestPlatte rausreist aber dann gib es eh wahrscheinlich ein Blue Screen).



  • Mehr als Augen zuhalten bzw. den Fehler lokale zu "behandeln" bleibt einem da in C++ nicht ...



  • Bashar schrieb:

    otze schrieb:

    assert im dtor sollte eigentlich zu undefiniertem verhalten führen oder?
    was passiert eigentlich, wenn man 2 objekte a und b hat, das erste wirft einen assert, damit wird das 2. objekt gekickt, welches wieder einen assert macht, wird der 2. aufruf dann ignoriert, oder bekommt man ein programm, welches im chaos untergeht?

    Du redest wirr. asserts werden nicht "geworfen" und haben auch kein undefiniertes Verhalten. Das Programm bricht einfach über die abort-Funktion ab. Das ist zwar oft unerwünscht, aber immer noch streng definiert. Kann es sein, dass du assert und Exceptions durcheinanderwirfst?

    monitor: Was meinst du mit "die eine Exception werfen könnte"? Tut sie oder nicht? Hier gilt eigentlich das gleiche wie immer mit assert: Wenn das Werfen einer Exception logisch gesehen nicht vorkommen kann (weil z.B. die Funktionsargumente so gewählt werden, dass die Funktion garantiert nicht wirft), dann ein assert. Wenn nicht vorhersehbare Einflüsse zur Laufzeit eine Exception erzeugen können, dann musst du dir was anderes einfallen lassen.

    soweit ich aber weis, werden noch alle dtors ordnungsgemäß abgearbeitet, und die frage war halt, was passiert, wenn assert aufgerufen wird, und ein dtor der danach aufgerufen wird wieder einen assert produziert.



  • otze schrieb:

    soweit ich aber weis, werden noch alle dtors ordnungsgemäß abgearbeitet,

    Das ist aber nicht so. Das Programm wird sofort und ohne Umwege abgebrochen.



  • dann hab ich mich wohl mal verlesen, sorry für den unqualifizierten post 🙂

    aber was ist mit etwaigen offenen resourcen wie sockets/files etc? wird da wieder alles ordnungsgemäß geschlossen bei einem assert?



  • aber was ist mit etwaigen offenen resourcen wie sockets/files etc? wird da wieder alles ordnungsgemäß geschlossen bei einem assert?

    Das sollte das Betriebssystem beim Sterben des Prozesses übernehmen. Darauf sollte man sich zwar nie verlassen - aber beim assert gehts nunmal nicht anders. Asserts sollten eh nur während der Entwicklung auftreten. Von daher...

    Hier wür ich dir raten den return Wert von CloseHandle einfach zu ignoriren, oder ein assert drum zu bauen.

    Das wäre ein Fehler, denn die Rückgabe von 0 ist ein definiertes Verhalten von CloseHandle. Ein assert wäre nur gerechtfertigt, wenn CloseHandle nur dann 0 zurückgibt, wenn der Fehler beim Aufrufer lag. Und ich meine, dem ist nicht zwingend so.


Anmelden zum Antworten