链接异常提供了对current_exception()的以下描述
如果在异常处理期间调用(通常在catch子句中),则捕获当前的异常对象,并创建一个std::exception_ptr,该对象包含该异常对象的副本或引用(取决于实现)。 ..。 如果此函数的实现需要复制捕获的异常对象,并且其复制构造函数抛出异常,则返回的指针将保存对抛出的异常的引用。如果抛出的异常对象的复制构造函数也抛出,则返回的指针可能保存对std::bad_exception实例的引用,以中断无穷无尽的循环。
我试图了解current_exception()在GCC7中的实现是复制捕获的异常对象,还是只返回对已经存在的对象的引用。到目前为止,我认为GCC实施了第二个案例。我试图通过执行以下代码来检查它:
class my_copy_exception : public exception
{
public:
my_copy_exception () : exception () {}
my_copy_exception (const my_copy_exception& other) :
exception(other)
{
throw my_copy_exception();
}
const char* what () const throw() {return "my_copy_exception";}
};
int main()
{
try
{
throw my_copy_exception();
}
catch (const exception& e)
{
cout << e.what() << endl;
exception_ptr eptr = current_exception();
try
{
rethrow_exception(eptr);
}
catch(const std::exception& en)
{
cout << en.what() << endl;
exception_ptr eptrn = current_exception();
cout << (eptr == eptrn) << endl;
}
}
}它产生以下输出:
my_copy_exception
my_copy_exception
1是否可以声称没有复制异常对象?如果不是,如何使current_exception()抛出bad_exception
发布于 2019-11-17 18:35:52
像GCC 7这样的开源软件的好处是,与其试图逆转它可能正在做的事情,不如去看看源代码,看看它到底在做什么。
在GCC 7.4的例子中,std::current_exception()的实现可以在libstdc++中找到,更具体地说,可以在ptr.cc 177号线中找到
std::exception_ptr
std::current_exception() noexcept
{
__cxa_eh_globals *globals = __cxa_get_globals ();
__cxa_exception *header = globals->caughtExceptions;
if (!header)
return std::exception_ptr();
// Since foreign exceptions can't be counted, we can't return them.
if (!__is_gxx_exception_class (header->unwindHeader.exception_class))
return std::exception_ptr();
return std::exception_ptr(
__get_object_from_ambiguous_exception (header));
}这里的前几行只获取当前活动的异常。如果没有活动异常,或者活动异常不是来自此C++运行时,则返回一个空exception_ptr (有关这些检查操作的详细信息,请参阅这里、这里、这里、这里、这里、这里和这里 )。如果有来自C++运行时的活动异常,则它将然后 获取 本身作为指向活动异常对象的指针,并构造exception_ptr。它使用的exception_ptr 构造函数仅仅是异常对象的引用计数器( 增量 )。
因此,在GCC 7的libstdc++实现中,libstdc++异常似乎是引用计数的,并且从来没有复制过,这符合规范的要求,并且似乎与您的观察…相匹配。
https://stackoverflow.com/questions/58880251
复制相似问题