invalid_argument exception fall trough



  • Da ich aus der Ausgabe meines Programms nicht schlau werde, möchte ich mir hier mal gerne Hilfe suchen!
    Ich habe jetzt mal das Kernproblem isoliert:

    #include <exception>
    #include <iostream>
    
    using namespace std;
    
    int main(void){
    	try{
    		throw new invalid_argument("invarg");
    	}
    	catch(exception const &e){
    		cout << e.what();
    	}
    	return 0;
    }
    

    Was ich nicht verstehe ist, dass ja invalid_argument von exception abgeleitet ist, aber trotzdem nicht mit dem catch Befehl gefangen wird. Stattdessen wird der Terminate handler aufgerufen, der folgende Ausgabe produziert:

    terminate called after throwing an instance of 'std::invalid_argument*'
    Aborted (core dumped)

    ------------------
    (program exited with code: 134)
    Press return to continue

    Heisst 'std::invalid_argument*' jetzt, dass ich catch(exception const *e)
    verwenden soll statt catch(exception const &e)? Natürlich würde ich gerne auf old fashioned Pointer verzichten.
    Wenn ich das Schlüsselwort const weglasse, was aber angeblich wichtig sein soll, dann erhalte ich das gleiche Ergebnis.

    Das einzige, was vielleicht noch erwähnenswert ist, ist dass mit catch(...) der
    Absturz verhindert werden kann. Aber das nützt in diesem Fall auch nicht viel, da ich ja gerne die Nachricht der Exception per .what() ausgeben möchte.

    Hat jemand ne Idee, wo ich nen Denkfehler habe?
    Vielen Dank schonmal im Vorraus.
    [code="cpp"][code="cli"]



  • Sorry, ich hatte darauf geachtet, dass der Code richtig dargestellt wird und habe die Grütze am unteren Ende übersehen.

    Also bedanke ich mich nochmal im Voraus und bitte darum, über die Grütze
    hinwegzusehen.



  • Warum verwendest du überhaupt new beim Werfen der Exception?

    throw invalid_argument("invarg");
    

    s.a. Ideone-Code

    Wenn du beides (sowohl Zeiger als auch Referenzen) fangen willst, so benötigst du 2 catch-Handler.



  • Ja, jetzt erscheint es mir logisch. Da ich new beim Werfen der Exception verwendet habe, wird zwar wie geplant ein neues Exception Objekt erzeugt. Allerdings ist der Rückgabewert von new ja ein Pointer auf den Typ. Daher will der Compiler auch ein Pointer im catch Statement sehen. Wenn ich das new weglasse, wird das komplette Objekt entweder als Kopie (ohne & im catch) bzw. als Referenz (mit & im catch) an den Exception Handler weitergereicht. Der const Spezifizierer hat damit gar nichts zu tun und deshalb ist es auch egal ob ich ihn weglasse oder nicht.

    Das war wirklich eine schöne Lektion. Der Compiler hat offensichtlich logischer "gedacht" als ich.



  • Der Compiler setzt in diesem Fall einfach nur korrekt den Standard um. Und der definiert ganz klar was hier zu passieren hat. Nämlich das was du beobachtet hast.

    BTW: Zeiger Werfen in C++ ist eine ganz ganz schlechte Idee. catch (...) hat gefälligst zu funktionieren. Leakt aber dummerweise, sobald man Zeiger auf neu erzeugte Objekte wirft.


Log in to reply