TRY-CATCH (Exception Handling)



  • Hallo

    ich wollte mich eingentlich nicht auf die Division durch Null versteifen.
    Mit folgenden Programm habe ich das gleiche Problem!!!

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include <exception>
    #include <stdexcept>

    using namespace std;

    int main() {
    FILE *datei;

    // datei = fopen("datei.txt" ,"w");

    try {
    fputs("Hallo Datei" ,datei);
    }
    catch (...)
    {
    cout << "Fehler";
    }

    printf("\nende\n");
    fclose(datei);

    }

    Hier wurde einfachmal das öffnen der Datei vergessen (logisch ist ein fehler, deshalb möchte ich try-catch benutzten)
    Das Programm wurde wieder mit "g++ -otest -fexception test.cpp" compiliert.

    Beim Ausführen der Datei kommt dann "Segmentation fault"!!!
    Es muss dioch irgendwas geben um das Exception-Handling akt. zu können

    Gruß
    JUschold



  • Hi,

    bist Du sicher, dass "div-by-zero" überhaupt eine exception wirft ?
    Ein "Segmentationfault" wie beim Zugriff auf eine ungültige Adresse ("Nullpoiner", put auf ungeöffnetes File) tut es IIRC auch nicht...
    Man kann einfach nicht alles Fehlersituationen mit einem try/catch abfangen ... sonst hätten die das in Word&Co schon längst eingebaut. 😉

    Du kannst nur exceptions fangen, wo welche geworfen werden - und das liegt üblicherweise im Ermessen des Programmierers der aufgerufenen Funktion. Wenn der eine technisch notwendige Bedingung nicht abprüft und eine exception wirft, "krachts" eben.

    OT:

    juschold schrieb:

    ...
    cout << "!!!! FEHLER !!!!\n" ;
    }
    
    printf("\n ende \n");
    

    ...

    Sooo dicht beieinander habe ich das bislang noch nie gesehen. 😉

    Gruß,

    Simon2.

    P.S.: Nutz doch bitte die code-Markierung beim Posten; kostet Dich nicht viel und macht es allen hier deutlich leichter.



  • Wieso tuts es im Windows VC++ 6.0 ????

    Gruß
    JUschold



  • juschold schrieb:

    Es muss dioch irgendwas geben um das Exception-Handling akt. zu können

    Wie gesagt - C kannte noch keine Exception-Behandlung (schau dir mal den Link oben an - so funktioniert das in C). Da wäre es wohl die beste Lösung, komplett auf C++ Funktionalität auszuweichen (fstreams werfen zwar keine Exception, wenn du vergisst, sie zu öffnen - aber wenigstens schrotten sie nicht dein Programm).



  • juschold schrieb:

    Wieso tuts es im Windows VC++ 6.0 ????

    Gruß
    JUschold

    Weil der Programmierer von Windows-implementation der StandardLib das eben so programmiert hat. Vielleicht hast Du bei ubuntu auch eine spezielle "throw-arme" Version erwischt ....
    Da Du aber hier C-Funktionen verwendest (fopen() & Co), bin ich seeeehr skeptisch, dass dieses Beispiel unter VC++6.0 wie gewünscht läuft.

    Ob try/catch prinzipiell funktioniert, kannst Du am besten testen, wenn Du selbst mal eine exception wirfst/fängst.

    juschold schrieb:

    :::
    Es muss dioch irgendwas geben um das Exception-Handling akt. zu können...

    Wenn ein Fehler in der Hardware festgestellt und da ein entsprechender Interrupt ausgelöst wird, kommst Du (ein vernünftiges Betriebssystem vorausgesetzt) nicht mehr sinnvoll "in Deine Programmumgebung" zurück ... da ist auch nix mehr mit "catch". Du könntest höchstens einen Interrupthandler installieren ... damit wirst Du aber wohl mehr Probleme bekommen als lösen.

    Letztlich ist die Lösung zu Deinem Problem ganz einfach: Prüfe Du die Konsistenz Deines Programmzustands, bevor Du eine Funktion aufrufst !
    (Ehrlich gesagt habe ich das als hauptsächlichen Unterschied zwischen C++- und Java-Programmierern empfunden: Während Erstere sich intensiv damit auseinandersetzen, was schief gehen kann, programmieren Zweitere nur den Gutfall und "Wenn's nicht klappt, wirft schon irgendjemand eine exception") 😉

    Gruß,

    Simon2.



  • Hallo

    habs gerade im VC++ nochmals ausprobiert. Da gehts ohne Probleme1!!!
    Er bricht erst beim "fclose(datei)" datei ab. (logisch)

    Gruß
    JUschold



  • Hallo,

    fgets kennt mit ziemlicher Sicherheit keine Exceptions. Auch in VC++ führt das nur deshalb (und möglichweise auch nur in der Debug-Version) zu einem Fehler, weil Microsoft dort den "catch(...)" so implementiert hat, das er auch Ausnahmefehler fängt (die du mit deinem Code ja provozieren willst).

    Der GCC tut das definitiv nicht. Wenn keine Exception geworfen wird (wie, beispielsweise, bei deinem Code der Fall), dann läuft er definitiv NICHT in den catch(...) Block.

    Du kannst auch prüfen, ob es sich um eine Exception handelt, indem du den catch(std::exception) verwendest. Ein solcher Block wird auch in VC nur dann angelaufen, wenn eine std::exception gefangen wurde.



  • juschold schrieb:

    Wieso tuts es im Windows VC++ 6.0 ????

    Du musst zwischen C++ Exceptions und Windows-Exceptions (Stichwort: Structured Exception Handling) unterscheiden. C++ Exceptions müssen explizit mit throw geworfen werden und können mit catch gefangen. Der C++ Standard definiert für einige wenige Standardlib-Funktionen, dass sie bestimmte Exceptions werfen. Für das Ausführungssystem selbst sind aber keinerlei Exceptions definiert. D.h. Dinge wie Dereferenzieren eines Nullzeigers, Division durch Null usw. führen zu undefiniertem Verhalten nicht zum Wurf einer C++ Exception.

    Unter Windows gibt es nun noch das Structured Exception-System, dass sowohl Hardware-Exceptions (also solche, die z.B. durch die CPU ausgelöst werden), als auch Software-Exceptions (solche die durch das BS ausgelöst werden) auf vom Programm fangbare Exceptions abbildet. Im Visual Studio verwendet man hier normalerweise __try und __catch. Eine Eigenheit des VCs ist es aber, dass ein catch(...) auch Windows-Exceptions fängt (also nicht nur C++ Exceptions). Das ist aber kein Verhalten, dass so vom C++ Standard vorgeschrieben ist. Der Standard gibt dir *keine* Möglichkeit solche Low-Level-Fehler abzufangen. Es gibt natürlich Wege, die sind aber *immer* platform-spezifisch.



  • Hallo

    danke, ich glaube jetzt habe ich es verstanden!!!



  • Um Hume etwas zu ergänzen: Im VC wird C++-exception-handling mit Hilfe des structured exception handlings implementiert, deswegen fängt er mit dem catch-all block auch diese anderen exceptions.


Anmelden zum Antworten