在堆栈展开期间我可以使用std :: current_exception吗?

时间:2015-02-01 20:28:47

标签: c++ c++11 exception-handling

是否可以在堆栈展开期间销毁的对象的析构函数中使用std :: current_exception?

Documentation on cppreference说:

  

如果在异常处理期间调用(通常在catch子句中),则捕获当前异常对象(...)

但我不清楚堆栈展开是否是异常处理的一部分。

在stackoverflow上的一些highest-ranked answer中,作者假定它是可能的。

我对我的编译器进行了一些测试(g ++(Ubuntu 4.8.2-19ubuntu1)4.8.2),似乎在这种情况下std :: current_exception返回空指针。

#include <exception>
#include <stdexcept>
#include <iostream>


struct A
{
    ~A()
    {
        std::clog << "in destructor"<<std::endl;
        std::clog << "uncaught_exception: " << std::uncaught_exception() << std::endl;
        std::clog << "current_exception: " << (bool)std::current_exception() << std::endl;
    }
};

int main(int argc, char **)
{
    try
    {
        A aa;
        std::clog << "before throw"<<std::endl;
        if(argc>1)
            throw std::runtime_error("oh no");
    }
    catch(...)
    {
        std::clog << "in catch block"<<std::endl;
        std::clog << "uncaught_exception: " << std::uncaught_exception() << std::endl;
        std::clog << "current_exception: " << (bool)std::current_exception() << std::endl;
    }

    return 0;
}

输出结果为:

before throw
in destructor
uncaught_exception: 1
current_exception: 0
in catch block
uncaught_exception: 0
current_exception: 1

有人知道标准说的是什么吗?

1 个答案:

答案 0 :(得分:21)

C ++标准在第18.8.5节[传播]:

中定义current_exception()

(强调我的)

  

exception_ptr current_exception() noexcept;

     

返回:引用当前处理的exception_ptr对象   例外(15.3)或当前处理的例外的副本,或者a   如果没有处理异常,则为null exception_ptr对象。该   引用对象应至少在有效时保持有效   引用它的exception_ptr对象。

§15.3[except.handle],注7和8:

  
      
  1. 初始化完成后,处理程序被视为活动   catch子句的参数(如果有的话)。 [注意:堆栈将有   那时已经解开了。 - 尾注]

  2.   
  3. 最近激活的处理程序仍处于异常状态   活动称为当前处理的例外

  4.   

current_exception()返回的异常被定义为“当前处理的异常”,这是最新的活动处理程序的例外,并且仅当堆栈展开完成时处理程序才处于活动状态。


正如您的测试所示,在堆栈展开期间没有“活动处理程序”,因此也没有“当前处理的异常”:在这种情况下,current_exception()将返回null exception_ptr