2010-04-22 6 views
19

Ich stolperte diesen Code:Was "wirft" außerhalb eines catch block tun?

void somefunction() 
{ 
    throw; 
} 

und ich frage mich: was bedeutet es?


Ich markierte die Frage als C++ und Visual C++, weil ich die Antwort nicht kannte. Die Antwort könnte mit dem Standard oder einer speziellen Visual C++ - Erweiterung oder Visual C++, die den Standard ignoriert, in Beziehung stehen. Deshalb dachte ich, dass beide Tags gerechtfertigt sind.

+3

Diese Frage bezieht sich nicht auf Visual Studio oder irgendeine Art von "visuellem" C++. Bitte kennzeichnen Sie generische C++ - Fragen nicht mit konkreten Framework-Tags. –

+0

@Pavel Shved: Die Frage könnte mit VC++ zusammenhängen, wenn eine Art von Spracherweiterung anwendbar ist.In diesem Fall wäre es wünschenswert, sie auf dieser Grundlage zu beantworten und gleichzeitig auf die Antwort gemäß dem Standard hinzuweisen. –

+0

@David, @Tobias, ich denke, es ist besser, die Frage nicht als VC-bezogen zu kennzeichnen, wenn Sie nicht sicher sind. Die Community wird sie entsprechend neu schreiben, wenn es sich um eine Spracherweiterung handelt. –

Antwort

28

Natürlich ist es möglich, dass somefunction() nur innerhalb von einigen catch Block aufgerufen wird (bei einer Schätzung, das ist wahrscheinlich die Absicht sowieso). Wenn die throw; ausgeführt wird, wenn eine Ausnahme nicht aktiv ist, ruft sie terminate() (§15.1/8) auf.

9

Es wird die aktuell aktive Ausnahme erneut ausgelöst. Es wäre nur sinnvoll, sie (möglicherweise indirekt) von einem Catch-Block aus aufzurufen. Dies ist:

#include <iostream> 
using namespace std; 

void f() { 
    throw; 
} 

int main() { 
    try { 
     try { 
      throw "foo"; 
     } 
     catch(...) { 
      f(); 
     } 
    } 
    catch(const char * s) { 
     cout << s << endl; 
    } 
} 

druckt "foo".

4

Für throw das Konzept von "außerhalb" oder "innen" catch-Block ist in Laufzeiten definiert, nicht in der Kompilierung Begriffe wie Sie zu übernehmen scheinen. Wenn also während der Laufzeit throw im Laufzeitkontext eines catch Blocks ausgeführt wird, funktioniert throw wie erwartet. Andernfalls wird terminate() aufgerufen.

In der Tat, wenn Sie genauer betrachten, wie C++ - Ausnahmen in der Sprachspezifikation definiert sind, eine Menge Dinge über sie sind in Laufzeit definiert. Manchmal scheint es sogar un-C++ - ähnlich zu sein.

+0

Nein, ich habe so etwas nicht angenommen. Aber ich habe die Verwendung der Funktion nicht ausreichend kommentiert. Entschuldigen Sie das Missverständnis. –

3

Die Leute haben bereits erklärt, was es bedeutet, aber es ist möglicherweise nützlich zu wissen, warum Sie es vielleicht sehen. Es ist ein nützlicher Weg, um einen 'generischen' Exception-Handler zu konstruieren, der Ausnahmen basierend auf ihrem Typ behandelt, um die Menge an doppeltem Code zu reduzieren.

Also, wenn wir Neil's example und erweitern, was f() könnten wir mit einer Implementierung, die etwas tut, am Ende tun könnte wie meine LogKnownException() Funktion, die ich in this answer vorgeschlagen.

Wenn Sie in einem Team arbeiten, das alle Arten von Ausnahmen überall protokolliert, anstatt eine riesige Sammlung von Catch-Blöcken an allen diesen Stellen zu haben (oder noch schlimmer, ein Makro), können Sie ein einfaches haben catch-Block, die Obwohl ich wie dieser erwarte

catch(...) 
{ 
    LogKnownException(); 
} 

sieht würde ich mein vorheriges Beispiel LogKnownException() zu einem ändern, die nur Ausnahmen erlaubt, dass es nicht in einer nicht behandelt Art und Weise zu verbreiten und weiter auf loggt sein wollte.

Ich schlage nicht vor, dass dies unbedingt eine gute Sache zu tun ist, nur darauf hinweist, dass hier wahrscheinlich das Konstrukt verwendet wird.