是否可以在堆栈展开期间销毁的对象的析构函数中使用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
有人知道标准说的是什么吗?
答案 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:
初始化完成后,处理程序被视为活动 catch子句的参数(如果有的话)。 [注意:堆栈将有 那时已经解开了。 - 尾注]
- 醇>
最近激活的处理程序仍处于异常状态 活动称为当前处理的例外。
current_exception()
返回的异常被定义为“当前处理的异常”,这是最新的活动处理程序的例外,并且仅当堆栈展开完成时处理程序才处于活动状态。
正如您的测试所示,在堆栈展开期间没有“活动处理程序”,因此也没有“当前处理的异常”:在这种情况下,current_exception()
将返回null exception_ptr
。