开发者

what does "throw;" outside a catch block do?

I just stumbled this code:

voi开发者_StackOverflow社区d somefunction()
{
   throw;
}

and I wonder: what does it mean?


The intent is probably that somefunction() is only ever called from inside some catch block. In that case, there would be an exception active when the throw; is executed, in which case the current exception is re-thrown, to be caught by the next outer handler that can handle that exception type.

If throw; is executed when an exception is not active, it calls terminate() (N4810, §[expr.throw]/4).


It re-throws the currently active exception. It would only make sense to call it (possibly indirectly) from a catch-block. This:

#include <iostream>
using namespace std;

void f() {
    throw;
}

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

prints "foo".


For throw the concept of being "outside" or "inside" catch block is defined in run-time terms, not in compile-time terms as you seem to assume. So, if during run-time that throw is executed in run-time context of a catch block, then throw works as expected. Otherwise, terminate() is called.

In fact, if you take a closer look at how C++ exceptions are defined in the language specification, a lot of things about them are defined in run-time terms. Sometimes it even appears to be un-C++-like.


People have already explained what it means but it's potentially useful to know why you might see it. It's a useful way to construct a 'generic' exception handler that deals with exceptions based on their type so as to reduce the amount of duplicated code.

So, if we take Neil's example and expand on what f() might be doing we might end up with an implementation which does something like my LogKnownException() function that I proposed in this answer.

If you are working in an team that likes to log all manner of exceptions all over the place then rather than having a huge collection of catch blocks at all of these places (or even worse a macro) you can have a simple catch block that looks like this

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

Though I expect I'd change my previous example of LogKnownException() to one that simply allowed exceptions that it didn't want to log to propagate out and continue on in an unhandled fashion.

I'm not suggesting that this is necessarily a good thing to do, just pointing out that this is where you're likely to see the construct used.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜