【问题标题】:How to detect when an exception is in flight?如何检测异常何时发生?
【发布时间】:2010-11-14 08:00:37
【问题描述】:

在 C++ (MSVC) 中,我如何测试异常当前是否“正在运行”。即,作为类析构函数的一部分被调用的代码可能会被调用,因为异常正在展开堆栈。. 我如何检测这种情况,而不是由于正常返回而调用析构函数的正常情况?

【问题讨论】:

  • 我觉得我应该捍卫我想要这样做的理由。当我的一段代码崩溃时,我想写出一些调试状态。为此,我想将一些日志记录代码放入析构函数中,该析构函数将写出一些内部状态。我不希望在每个析构函数调用中都这样,因为在我的测试设置中它会在失败之前正常运行几次迭代。所以.. 在我的析构函数中,我现在使用“if (uncaught_exception()) {..}”来启用一些额外的日志记录。调试器对我来说还不够,因为我需要进行大量昂贵的转换才能使内部状态可读。

标签: c++ exception visual-c++


【解决方案1】:

我不确定是否有更好的方法,但你能不捕获并重新抛出异常吗?

【讨论】:

    【解决方案2】:

    一种方法是用您的own 替换异常处理机制。

    另一方面,它总是引出一个问题——为什么要这样做?..

    关于主题的更多链接:Reversing Microsoft Visual C++ Part I: Exception HandlingThe exception model

    【讨论】:

      【解决方案3】:

      你可能正在寻找

      // Returns true only if a thrown exception is being currently processed
      namespace std {
          bool uncaught_exception();
      };
      

      http://msdn.microsoft.com/en-us/library/k1atwat8.aspx

      【讨论】:

        【解决方案4】:

        其实是可以的,在头中调用uncaught_exception()。 您可能想要这样做的一个原因是在析构函数中引发异常之前,如果此析构函数作为堆栈展开的一部分被调用,这将导致程序终止。 见http://msdn.microsoft.com/en-us/library/k1atwat8%28VS.71%29.aspx

        【讨论】:

        • 这很好用,我一定是在谷歌上搜索了错误的关键字才没有发现这个。 :)
        • 请注意,虽然这告诉您是否存在异常,但了解该事实几乎没有用处。特别是,当在析构函数中使用时,它不会告诉您是否可以/应该在失败时抛出异常:gotw.ca/gotw/047.htm
        • 析构函数永远不应该抛出任何异常。
        【解决方案5】:

        在 uncaught_exception() 路径走得太远之前,请查看 http://www.gotw.ca/gotw/047.htm

        【讨论】:

          【解决方案6】:

          在 C++17 中,引入了std::uncaught_exceptions(注意复数“s”)。这允许您捕获 ctor 中的“嵌套展开”计数,并将捕获的值与执行 dtor 时的当前值进行比较。这样您就可以知道您的对象是否因为异常(dtor 当前值 > 捕获值)而离开其范围而被销毁。

          这意味着你终于可以在 C++ 中实现诸如“自动撤消”保护之类的东西了,是的。 :)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-08-03
            • 2019-01-25
            • 1970-01-01
            • 2020-09-29
            • 1970-01-01
            • 2016-11-21
            • 2013-05-01
            • 2012-03-14
            相关资源
            最近更新 更多