Problem mit throw()



  • void foo(void) throw() //<=====
    {
        throw "Fehler";
    };
    
    void handler(void)
    {
        exit(1);
    };
    
    int main(int argc,char** argv)
    {
        set_unexpected(handler);
    
        try
        {
    	foo();
        }
        catch(char* Text)
        {
    	cout << "Exception abgefangen!"<<endl;
        };
    
        return 0;
    };
    

    Hallo,
    die Funktion foo soll keine Exception auslösen düfen,deshalb habe ich in der Signatur auch throw().
    Mein Problem ist,dass die Exception,die in foo ausgelöst wird einfach abgefangen wird. Es müsste doch handler aufgerufen und das Programm beendet werden.
    Warum wird mein throw() "ignoriert"?

    Danke



  • throw() heisst, dass Du dem Aufrufer Deiner Funktion gerantierst, dass Deine Funktion keine Exception werfen wird. Das heisst, eine Funktion die throw() in ihrer Signatur stehen hat, darf keine Exception werfen. Du wirfst aber eine Exception...

    Edit: Achso, darauf willst Du hinaus...

    Also bei mir läuft folgendes:

    #include <iostream>
    #include <exception>
    
    void test(){
        std::cerr << "Error\n";
        std::exit(1);
    }
    
    void bla() throw(){
        throw 0;
    }
    
    int main(){
        std::set_unexpected(test);
        try{
            bla();
        }
        catch(...){
            std::cerr << "Catched error\n";
        }
    }
    

    Ausgabe:
    Error



  • Ich tippe mal auf einen schlechten Compiler.
    Der MS VS6.0 z.B. ignoriert einfach exception specifications ...

    Vielleicht kann man das auch abschalten...
    welchen Compiler hast Du denn ?

    Gruß,

    Simon2.



  • Ich benutze Microsoft Visual C++ 2008 Express (/EHsc)



  • Programmierer schrieb:

    Ich benutze Microsoft Visual C++ 2008 Express.

    Und wie ist der Kompilerswitch /EH ??
    http://msdn.microsoft.com/de-de/library/1deeycx5.aspx
    Simon



  • @Programmierer
    Der catch Zweig passt auch nicht. Du wirfst ein const char* und willst ein char* fangen.



  • Braunstein schrieb:

    @Programmierer
    Der catch Zweig passt auch nicht. Du wirfst ein const char* und willst ein char* fangen.

    Was dann aber eher dafür sprechen würde, dass die exception nicht gefangen und der unexpected handler aufgerufen wird. Das ist aber ja genau nicht der Fall.
    Simon



  • Ich hatte den Code bei mir getestet (CodeBlocks mit MinGW) und da verhielt sich der Compiler wie erwartet.
    Wenn throw() gesetzt war, wurde der unexpected-handler aufgerufen.
    Wenn throw() nicht gesetzt war, wurde das Programm abgebrochen (Exception nicht gefangen).
    Wenn im catch-Zweig const char* stand, wurde die Exception gefangen.

    Der VC8 scheint sich da anders zu verhalten. Er gibt aber eine Warnung bezüglich foo raus.

    [edit]Ich habs gerade noch mal mit dem BCB2007 getestet und der verhält sich wie der MinGW.[edit]



  • Komisch.
    MSVC kann zwar keine "nicht-leeren" throw-specs, aber MS behauptet zumindest dass "throw()" korrekt unterstützt wird (ab 2003 oder 2005 - auf jeden Fall vor 2008). Auch Käse wenn das in echt garnicht geht 😞


  • Mod

    hustbaer schrieb:

    Komisch.
    MSVC kann zwar keine "nicht-leeren" throw-specs, aber MS behauptet zumindest dass "throw()" korrekt unterstützt wird (ab 2003 oder 2005 - auf jeden Fall vor 2008). Auch Käse wenn das in echt garnicht geht 😞

    vc unterstützt Exceptionspezifikationen grundsätzlich nicht. Das ist eine bewusste Designentscheidung - wenn sie auch dem Standard widersprechen mag. Wird die Spezifikation verletzt, ist das Verhalten dann undefiniert (und löst eben nicht zwingend den Aufruf von unexpected() aus). Eine leere Exceptionspezifikation kann demgemäß für zusätzliche Optimierungen genutzt werden (eine Eigenheit von vc ist z.B., dass Funktionen, die eine Klassenobjekt zurückgeben, dessen Destruktor möglicherweise eine Exception wirft, niemals inline-expandiert werden - eine leere Exceptionspezifikation beim Destruktor kann hier mitunter abhelfen).



  • Braunstein schrieb:

    ...Der VC8 scheint sich da anders zu verhalten....

    camper schrieb:

    ...vc unterstützt Exceptionspezifikationen grundsätzlich nicht....

    Sag ich doch:

    Simon2 schrieb:

    Ich tippe mal auf einen schlechten Compiler.
    Der MS VS6.0 z.B. ignoriert einfach exception specifications ...

    😃 😃

    Gruß,

    Simon2.



  • camper schrieb:

    hustbaer schrieb:

    Komisch.
    MSVC kann zwar keine "nicht-leeren" throw-specs, aber MS behauptet zumindest dass "throw()" korrekt unterstützt wird (ab 2003 oder 2005 - auf jeden Fall vor 2008). Auch Käse wenn das in echt garnicht geht 😞

    vc unterstützt Exceptionspezifikationen grundsätzlich nicht. Das ist eine bewusste Designentscheidung - wenn sie auch dem Standard widersprechen mag. Wird die Spezifikation verletzt, ist das Verhalten dann undefiniert (und löst eben nicht zwingend den Aufruf von unexpected() aus). Eine leere Exceptionspezifikation kann demgemäß für zusätzliche Optimierungen genutzt werden (eine Eigenheit von vc ist z.B., dass Funktionen, die eine Klassenobjekt zurückgeben, dessen Destruktor möglicherweise eine Exception wirft, niemals inline-expandiert werden - eine leere Exceptionspezifikation beim Destruktor kann hier mitunter abhelfen).

    Du hast Recht, und hier isses sogar dokumentiert:
    http://msdn.microsoft.com/en-us/library/wfa0edys(VS.80).aspx

    Ich hatte diese Seite in Erinnerung:
    http://msdn.microsoft.com/en-us/library/skce93f2(VS.80).aspx
    ...und da ist das mit den knappen Worten "parsed and used" beschrieben - was ich als "parsed and used (as dictated by the standard)" interpretiert hatte.


Anmelden zum Antworten