如何检测析构函数期间异常是否处于活动状态?
在 C++ 中,如何在析构函数体内检测堆栈是否由于抛出异常而被展开?一旦检测到,我可以获得对活动异常的引用吗?
我问这个问题是因为我想添加一些调试代码来解释为什么会出现某种情况以及它是否是由于异常引起的。
In C++, how can I detect in the body of my destructor whether the stack is being unwound due to an exception being thrown? Once detected, can I get a reference to the active exception?
I ask because I'd like to add some debugging code that explains why a certain situation may arise and whether it is due to exceptions or not.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
std::uncaught_exception
告诉您堆栈是否由于抛出异常而被展开,这正是您所要求的。但是,它并没有告诉您可能想知道的内容:您从中调用其析构函数的对象是否位于正在展开的堆栈部分,或者由于非正常原因而被正常销毁的堆栈部分。异常退出属于展开一部分的其他析构函数下的作用域:
与 DeadMG 和 Xeo 所说的相反,您无法获得对尚未捕获的异常的引用。没有操作数的
throw
会重新抛出“当前处理的异常”,也就是说您所在的 catch 处理程序中的异常,或者其 catch 处理程序已调用您的异常。它不会重新抛出未捕获的异常。std::uncaught_exception
tells you whether the stack is being unwound due to an exception being thrown, which is what you asked.However, it doesn't tell you what you probably want to know: whether the object whose destructor you call it from, is in the part of the stack that's being unwound, or the part of the stack that's being destroyed normally due to non-exceptionally exiting a scope beneath some other destructor that is part of the unwind:
Contrary to what DeadMG and Xeo say, you cannot get a reference to an exception that has not been caught.
throw
with no operand rethrows the "currently handled exception", that is to say an exception whose catch-handler you are in, or whose catch-handler has called you. It does not rethrow an uncaught exception.C++17 的新
std::uncaught_exceptions()
怎么样?我认为您可以构建如下所示的代码:在这种情况下,std::uncaught_exceptions() 跟踪调用代码时未捕获的异常的数量。更多信息可以在其 cppreference 页面上找到。
What about C++17's new
std::uncaught_exceptions()
? I think you can build a code that looks like this:In this case,
std::uncaught_exceptions()
tracks the number of uncaught exceptions by the time the code is called. More info can be found on its cppreference page.有一个 std::uncaught_exception() 函数。然而,要尝试访问异常对象,您可以做的唯一有用的事情就是重新抛出它并尝试捕获它。一般来说,您不应该从任何析构函数中抛出异常。
There is a
std::uncaught_exception()
function. However, about the only useful thing you can do to attempt to gain access to the exception object is rethrow it and try to catch it. You should never throw exceptions from any destructor, in general.不是。
不。
Not.
No.