【发布时间】:2011-01-29 06:53:16
【问题描述】:
如果在我的代码中我有以下 sn-p:
try {
doSomething();
} catch (...) {
doSomethingElse();
throw;
}
throw 是否会重新抛出默认省略号处理程序捕获的特定异常?
【问题讨论】:
标签: c++ exception throw ellipsis
如果在我的代码中我有以下 sn-p:
try {
doSomething();
} catch (...) {
doSomethingElse();
throw;
}
throw 是否会重新抛出默认省略号处理程序捕获的特定异常?
【问题讨论】:
标签: c++ exception throw ellipsis
是的。异常在被捕获之前一直处于活动状态,此时它变为非活动状态。但是它会一直存在到处理程序的范围结束。从标准来看,强调我的:
§15.1/4:被抛出异常的临时副本的内存以未指定的方式分配,除非在 3.7.4.1 中注明。 只要有针对该异常的处理程序正在执行,临时性就会持续存在。
即:
catch(...)
{ // <--
/* ... */
} // <--
在这些箭头之间,您可以重新抛出异常。只有在处理程序范围结束时,异常才会停止存在。
事实上,在 §15.1/6 中给出的示例与您的代码几乎相同:
try {
// ...
}
catch (...) { // catch all exceptions
// respond (partially) to exception <-- ! :D
throw; //pass the exception to some
// other handler
}
请记住,如果您 throw 没有活动异常,则将调用 terminate。在处理程序中,这对您来说不是这种情况。
如果doSomethingElse() 抛出并且异常没有相应的处理程序,因为原始异常被认为已处理,新异常将替换它。 (好像它刚刚抛出,开始堆栈展开等)
即:
void doSomethingElse(void)
{
try
{
throw "this is fine";
}
catch(...)
{
// the previous exception dies, back to
// using the original exception
}
try
{
// rethrow the exception that was
// active when doSomethingElse was called
throw;
}
catch (...)
{
throw; // and let it go again
}
throw "this replaces the old exception";
// this new one takes over, begins stack unwinding
// leaves the catch's scope, old exception is done living,
// and now back to normal exception stuff
}
try
{
throw "original exception";
}
catch (...)
{
doSomethingElse();
throw; // this won't actually be reached,
// the new exception has begun propagating
}
当然,如果没有抛出任何异常,throw; 将被访问,您将按预期抛出捕获的异常。
【讨论】:
terminate 被调用;请参见示例的最后一行,throw 2;,其中2 是抛出的新异常。
throw "this replaces the old exception"; 永远不会到达,因为函数以 throw; // and let it go again 结尾。