我可以在堆栈展开期间使用 std::current_exception 吗?
Can I use std::current_exception during stack unwinding?
是否可以在堆栈展开期间销毁的对象的内部析构函数中使用 std::current_exception?
Documentation on cppreference 说:
If called during exception handling (typically, in a catch clause), captures the current exception object (...)
但我不清楚堆栈展开是否是异常处理的一部分。
在 Whosebug 上的一些 highest-ranked answer 中,作者认为这是可能的。
我对我的编译器 (g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2) 做了一些测试,在这种情况下似乎 std::current_exception returns 空指针.
#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
有人知道标准是怎么说的吗?
C++ 标准在第 18.8.5 节 [传播] 中定义 current_exception()
:
(强调我的)
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.
和 § 15.3 [except.handle],注释 7 和 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.
由current_exception()
编辑的异常return定义为"currently handled exception",这是最近活动的处理程序的异常,只有当堆栈展开完成时处理程序才处于活动状态.
如您的测试所示,在 堆栈展开期间没有 "active handler" ,因此也没有 "currently handled exception":在这种情况下,current_exception()
将 return 为 null exception_ptr
.
是否可以在堆栈展开期间销毁的对象的内部析构函数中使用 std::current_exception?
Documentation on cppreference 说:
If called during exception handling (typically, in a catch clause), captures the current exception object (...)
但我不清楚堆栈展开是否是异常处理的一部分。
在 Whosebug 上的一些 highest-ranked answer 中,作者认为这是可能的。
我对我的编译器 (g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2) 做了一些测试,在这种情况下似乎 std::current_exception returns 空指针.
#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
有人知道标准是怎么说的吗?
C++ 标准在第 18.8.5 节 [传播] 中定义 current_exception()
:
(强调我的)
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.
和 § 15.3 [except.handle],注释 7 和 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.
由current_exception()
编辑的异常return定义为"currently handled exception",这是最近活动的处理程序的异常,只有当堆栈展开完成时处理程序才处于活动状态.
如您的测试所示,在 堆栈展开期间没有 "active handler" ,因此也没有 "currently handled exception":在这种情况下,current_exception()
将 return 为 null exception_ptr
.