Exception die gefangen werden muss.



  • Kann man in C++ eine Funktion so deklarieren, dass sie eine exception werfen kann und es einen Compilefehler gibt, wenn diese nicht gefangen wird. Also so wie Exceptions in Java?



  • Hallo

    Ich habe leider keine große Ahnung von exceptions, aber werden diese nicht immer erst zur Laufzeit geworfen und somit überprüft, ob ein bestimmter Codeabschniit funktioniert hat. Was hat das mit dem compilen zu tun?

    Ich lasse mich übrigens sehr gerne aufklären.

    chrische



  • Nein, in C++ gibt es keinen Zwang die Exceptions zu fangen.



  • chrische5 schrieb:

    Hallo

    Ich habe leider keine große Ahnung von exceptions, aber werden diese nicht immer erst zur Laufzeit geworfen und somit überprüft, ob ein bestimmter Codeabschniit funktioniert hat. Was hat das mit dem compilen zu tun?

    Ich lasse mich übrigens sehr gerne aufklären.

    Er meint was anderes: in Java bist du gezwungen bei bestimmten Funktionen, die eine Exception werfen können, einen try-catch-Block um den Aufruf zu bauen. Wenn nicht, meldet sich der Compiler das du das bitte machen sollst.

    Aber das gibt es in C++ nicht. Wenn du kein try-catch-Block um den Aufruf baust und es zur Laufzeit knallt, hast du Pech.



  • Natürlich wird die Exception erst zur Laufzeit geworfen, aber ich will das der Programmierer gezwungen wird ein catch hinzuschreiben oder sie weiter zu werfen. Wenn das nicht gemacht wird, dann soll es eine Fehlermeldung schon beim compilieren geben. Damit wird die Fehlerbehandung viel einfacher. Wenn die Exceptions nur geworfen werden, aber sie keiner fängt gibt es ja nur nen Programmabsturz von dem keiner was hat.



  • Artchi schrieb:

    Nein, in C++ gibt es keinen Zwang die Exceptions zu fangen.

    Schade



  • Die Java-Philosophie ist ja gänzlich anders. Dort werden Exceptions für alles verwendet (siehe EOF-Exception). In C++ ist das nicht der Fall, dort schmeißt du eine Exception und der Benutzer fängt sie an einem Punkt wo es für ihn am besten ist.



  • Na so ähnlich ist es in Java auch möglich. Du kannst ja die Exception einfach weiter werfen und der nächste muss sie fangen. Ist aber nicht der sinn der Sache einfach alles weiter zu werfen und keine vernünftige exception Behandlung zu machen.



  • Hallo

    l00p schrieb:

    Natürlich wird die Exception erst zur Laufzeit geworfen, aber ich will das der Programmierer gezwungen wird ein catch hinzuschreiben oder sie weiter zu werfen. Wenn das nicht gemacht wird, dann soll es eine Fehlermeldung schon beim compilieren geben. Damit wird die Fehlerbehandung viel einfacher. Wenn die Exceptions nur geworfen werden, aber sie keiner fängt gibt es ja nur nen Programmabsturz von dem keiner was hat.

    Das hört sich für mich aber erstmal nach einer Menge Aufwand an. Es gibt ja auch Funktionen, wo ich mir ziemlich sicher sein kann, dass keine exception geworfen wird und für diese müsste ich dann trotzdem einen catch-Block schreiben?

    chrische



  • Aufwändig ist es nicht. Ich selber bin beruflich in Java eingespannt und kann sagen, das es eigentlich keinen Aufwand macht. Denn die IDEs unterstützen einen hier mit autom. Codecompletion. Soll heißen, während du deinen Code Tippst, bekommst du schon von der IDE angezeigt, das ein try-catch nötig ist. Danach genüg ein Mouseclick, und der try-catch ist komplett von der IDE aufgebaut.

    In C++ ist das nicht der Fall.

    Deine Argumentation "Ich kann mir ziemlich sicher sein das keine Exception auftritt" widerspricht 100% dem Sinn von Exceptions! Nämlich das sie Ausnahmenfehler sind (Betonung liegt auf "Ausnahme"). Ausnahme und "es könnte sicherlich nicht passieren" ist irgendwie... es bereitet mir einen Knoten im Hirn. 😉 Denn ein Fehler kann nunmal ausnahmsweise auftreten. Und dann? Gerade diese Scenarien will man ja mit sicherer Software vermeiden. Wenn du keinen try-catch einbaust, gehst du bewusst ein Risiko ein, deine Software abstürzen zu lassen. Ganz schlechte Denkweise!

    Das Konzept von Java bzgl. Exceptions finde ich nicht schlecht. Ich jedenfalls fange in C++ immer dann Exceptions ab, wenn ich weiß, das die Funktion eine werfen kann. D.h. ich muß es aus der Doku herauslesen, da mir der Compiler das nicht mitteilt.



  • Es gibt in C++ aber auch Ausnahmesituationen, die der Programmierer problemlos umschiffen kann 😉

    Nehmen wir mal ein einfaches Beispiel - die Methode vector<T>::at(). Diese Methode wirft eine Exception (out_of_range), wenn du einen unzulässigen Index übergibst. Allerdings kann der Compiler nicht feststellen, ob (und wie) dein Programm in diese Situation laufen kann:

    vector<int> data;
    ...
    
    data.at(100) = 4711;
    /*
      könnte zu einem Fehler führen, wenn data zu wenige Elemente enthält
      -> hier brauchst du einen try/catch, um den auftretenden Fehler auszuwerten
    */
    
    if(data.size()>100)
      data.at(100) = 4711;
    /*
      durch die if()-Abfrage ist sichergestellt, daß der Index in Ordnung ist
      -> kein try/catch zur Fehlerkontrolle nötig
    */
    


  • In Java ist das genauso. Da kannst du auch ein IndexOutOfBounds verhindern in dem du vorher die Size des Vectors abfragst. Aber du hast Recht: in dem Fall brauch ich trotzdem in Java ein try-catch.

    In C++ kann ich mir das aussuchen. Aber der Code wird in C++ dadurch nicht besser, nicht mal performanter oder veständlicher (kann es drehen und wenden wie ich will).



  • Artchi schrieb:

    In Java ist das genauso. Da kannst du auch ein IndexOutOfBounds verhindern in dem du vorher die Size des Vectors abfragst. Aber du hast Recht: in dem Fall brauch ich trotzdem in Java ein try-catch.

    Das ist nicht korrekt. IndexOutOfBoundExceptions leiten von RuntimeException ab. RuntimeException muss man nicht fangen, kann man aber.

    Meistens ist es _nicht_ sinnvoll, RuntimeExceptions zu fangen, weil sie auf Programmierfehler hinweisen und nicht mit einer lapidaren MessageBox "Fehler beim blabla" vertuscht werden sollten. Vielleicht höchstens in main noch fangen um einen Fehlerbericht zu senden.

    EDIT: Du schreibst, du arbeitest beruflich mit Java. Hast du nie einen Vector benutzt? 😕



  • Hallo,
    zum Thema Checked-Exceptions ist dieser Artikel zu empfehlen:
    http://www.mindview.net/Etc/Discussions/CheckedExceptions

    In C++ hat man eine andere Philosophie was Exceptions angeht: statt Exceptions auf allen Ebenen zu fangen (und im Zweifelsfall erneut zu werfen), schreibt man allen
    Code Exception-Sicher (wnn es geht die Strong- mindestens aber die Basic-Garantie), z.B. unter großzügiger Verwendung des RAII-Idioms, und lässt Exceptions soweit wie möglich propagaieren. Nur an Modul-Grenzen (bzw. Stellen wo eine (endgültige) Behandlung möglich ist) werden dann tasächlich try-catch-Blöcke eingesetzt. In C++ erkennt man Exception-Sicheren-Code also in der Regel daran, dass es so gut wie keine Try-Catch-Blöcke gibt.



  • Keine Sorge, ist in C++ alles nicht so problematisch. Es hat sicher seinen Sinn, dass man nicht zum Exception Handling gezwungen wird, denn u.U. will man den Fehler ja bewusst nach oben durchlassen (ich schreibe z.B. eine Bibliothek, die Berechnungen ausführt. Wenn mir der User allerdings falsche Argumente für die Berechnung übergibt, werfe ich eine Exception und der User muss sie behandeln - er hat es schließlich verbockt). Java wird dem Umstand wohl mit dem beschriebenen "weiterreichen" nachgekommen sein. Um aber zu Verhindern, dass das Programm unkontrolliert abstürzt, gibt es auch in C++ die Möglichkeit, ein allgemeines Handling vorzunehmen:

    #include <iostream>
    
    int function(int x);
    
    int main()
    {
        try {
            function(0);
        }
        catch(...)
        {
            std::cout << "Unbekannte Exception eingefangen!\n";
        }
    
        return 0;
    }
    
    int function(int x)
    {
        if (x <= 0)
        {
            throw int(0);
        }
        else
        {
            return x;
        }
    }
    

    catch(...) fängt alle Exceptions. Somit kann man auch auf unerwartete Exceptions reagieren und steht nicht im Regen, wenn die Exception bis zum Betriebssystem hochgeht und das Programm unsanft gekillt wird.


Anmelden zum Antworten