我可以在堆栈展开期间使用std :: current_exception吗? [英] Can I use std::current_exception during stack unwinding?
问题描述
是否可以在堆栈展开期间销毁的对象的析构函数中使用std :: current_exception?
在异常处理期间调用(通常在catch子句中)捕获当前异常对象(...)
但不清楚对于我来说,堆栈展开是否是异常处理的一部分。
在某些最高
我对我的编译器做了一些测试(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(哦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
在析构函数中
uncaught_exception:1
current_exception:0
在catch块中
uncaught_exception:0
current_exception:1
有人知道标准的含义吗?
C ++标准定义 current_exception()
in section§18.8.5 [propagation]:
(强调我)
exception_ptr current_exception()noexcept;
:一个exception_ptr对象,它引用当前处理的
异常(15.3)或当前处理的异常的副本,或者如果没有异常处理,则为
null exception_ptr对象。
引用对象应至少保持有效,只要有引用它的
exception_ptr对象。
and§15.3 [except.handle],note 7 and 8:
当catch子句的
参数(如果有)的初始化完成时,处理程序被视为活动。 [注意:堆叠将在此时释放
。 - end note]
- href =http://en.cppreference.com/w/cpp/error/current_exception>
最近激活的处理程序仍为
活动的异常称为current_exception()
定义为当前处理的异常,这是最近的活动处理程序的例外,并且处理程序仅在堆栈展开完成时有效。
如你的测试所示,在堆栈展开期间没有活动处理程序,因此没有当前处理的异常:在这种情况下,
current_exception()
将返回nullexception_ptr
。Should it be possible to use std::current_exception inside destructors of objects that are destroyed during stack unwinding?
Documentation on cppreference says:
If called during exception handling (typically, in a catch clause), captures the current exception object (...)
But it's not clear for me whether stack unwinding is a part of exception handling.
In some highest-ranked answer on stackoverflow author assumes that it's possible.
I did some test on my compiler (g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2) and it seems, that std::current_exception returns empty pointer in this case.
#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; }
The output is:
before throw in destructor uncaught_exception: 1 current_exception: 0 in catch block uncaught_exception: 0 current_exception: 1
Does anybody know what the standard says?
解决方案C++ Standard defines
current_exception()
in section § 18.8.5 [propagation] :(emphasis mine)
exception_ptr current_exception() noexcept;
Returns: An exception_ptr object that refers to the currently handled exception (15.3) or a copy of the currently handled exception, or a null exception_ptr object if no exception is being handled. The referenced object shall remain valid at least as long as there is an exception_ptr object that refers to it.
And § 15.3 [except.handle], notes 7 and 8 :
A handler is considered active when initialization is complete for the parameter (if any) of the catch clause. [ Note: The stack will have been unwound at that point. — end note ]
The exception with the most recently activated handler that is still active is called the currently handled exception.
The exception returned by
current_exception()
is defined as the "currently handled exception", which is the exception of the most recent active handler, and a handler is active only when stack unwinding completed.
As your tests have shown, there is no "active handler" during stack unwinding, so there is no "currently handled exception" either : in that case,
current_exception()
will return a nullexception_ptr
.这篇关于我可以在堆栈展开期间使用std :: current_exception吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!