C++ `std::terminate`如何知道对`std::exception`进行特殊处理?
这个 如果我取消注释该注释,则死亡消息将变为:C++ `std::terminate`如何知道对`std::exception`进行特殊处理?,c++,C++,这个 如果我取消注释该注释,则死亡消息将变为: terminate called after throwing an instance of 'A' Aborted (core dumped) std::terminate如何专门处理std::exceptions 我如何在自己的set\u terminate中模拟这一点?我试过了 terminate called after throwing an instance of 'A' what(): this is A Aborted (cor
terminate called after throwing an instance of 'A'
Aborted (core dumped)
std::terminate
如何专门处理std::exception
s
我如何在自己的set\u terminate
中模拟这一点?我试过了
terminate called after throwing an instance of 'A'
what(): this is A
Aborted (core dumped)
/。。。
int main(){
std::set_terminate([](){
printf(“抛出异常\n”);
std::exception_ptr eptr=std::current_exception();
std::exception*ptr=动态广播(eptr);
如果(ptr)
放置(ptr->what());
});
扔一个{};
}
但是它不会编译,因为有
dynamic\u cast
行。最有可能的原因是它只是尝试dynamic\u cast
将它转换为std::exception
,并调用虚拟what()
方法,如果动态转换成功。std::terminate
所做的事情可以用以下方法近似模拟:
//...
int main(){
std::set_terminate([](){
printf("exception thrown\n");
std::exception_ptr eptr = std::current_exception();
std::exception* ptr = dynamic_cast<std::exception*>(eptr);
if (ptr)
puts(ptr->what());
});
throw A{};
}
感谢您为我指明了正确的方向。显然是这样。@user4815162342有趣的是,我得到了
what():
行,即使我在链接文章中使用-fno-rtti
@PSkocik进行编译,也说明即使禁用了rtti,也会使用rtti的某些部分,这些部分是使异常工作的必要条件。通常这样的事情是使用编译器魔法完成的:内置和编译器特定的代码<代码>标准::终止在运行库的深处实现。libstdc++只是抛出当前异常并尝试捕获std::exception
。源代码:@PSkocik是的,链接文章明确指出了这一点。根据作者的发现,-fno rtti
仅禁用前端功能,如typeid
,但实现RTTI的meachanism仍然用于后台异常。结果表明,它无法尝试将dynamic\u cast
转换为std::exception
,因为dynamic\u cast
仅在对象处于同一层次结构时才起作用。如果不是,它甚至不会编译。@PSkocik:dynamic\u cast
ingexception\u ptr
没有意义,因为它是一个不透明类型,而不是一个文本指针。请注意,您可以替换std::rethrow\u exception(std::current\u exception()
仅使用抛出
。虽然它在捕获
之外看起来不合适,但它甚至在C++98上也能工作。你比我快了3或4秒。:)以前的版本仍然很有趣,因为我了解了std::rethrow_异常
和std::current_异常
,这两个都是C++11中的新功能。@user4815162342在您的注释前几秒钟就这样做了。您可能还需要一个catch(…)
--否则,抛出不属于子类的std::exception
可能会导致调用终止处理程序的循环。从声明的noexcept
抛出异常调用std:unexpected()
,默认情况下只调用std::terminate()
。。。
//...
int main(){
std::set_terminate([](){
printf("exception thrown\n");
std::exception_ptr eptr = std::current_exception();
std::exception* ptr = dynamic_cast<std::exception*>(eptr);
if (ptr)
puts(ptr->what());
});
throw A{};
}
std::set_terminate([](){
puts("exception thrown");
//^skip the demangling of the typeid that's normaly done
try { throw; }
catch(const std::exception& e){ puts(e.what()); }
catch(...){}
//^rethrow and catch
});