【问题标题】:Does throw inside a catch ellipsis (...) rethrow the original error in C++?throw 在 catch 省略号 (...) 内是否会重新抛出 C++ 中的原始错误?
【发布时间】:2011-01-29 06:53:16
【问题描述】:

如果在我的代码中我有以下 sn-p:

try {
  doSomething();
} catch (...) {
  doSomethingElse();
  throw;
}

throw 是否会重新抛出默认省略号处理程序捕获的特定异常?

【问题讨论】:

    标签: c++ exception throw ellipsis


    【解决方案1】:

    是的。异常在被捕获之前一直处于活动状态,此时它变为非活动状态。但是它会一直存在到处理程序的范围结束。从标准来看,强调我的:

    §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; 将被访问,您将按预期抛出捕获的异常。

    【讨论】:

    • 如果 doSomethingElse() 同时抛出其他东西怎么办?奇怪的事情。
    • “以及它被捕获的处理程序”听起来令人困惑。根据您引用的段落,没有必要达到它的近括号。
    • @jdk: terminate 被调用;请参见示例的最后一行,throw 2;,其中2 是抛出的新异常。
    • @Potatoswatter:它可以使用一些改写。但是当作用域中的最后一条语句被执行时,“处理程序执行”就会停止。 (范围结束。)
    • throw "this replaces the old exception"; 永远不会到达,因为函数以 throw; // and let it go again 结尾。
    猜你喜欢
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 2017-05-16
    • 2014-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多