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 null exception_ptr
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.