【问题标题】:How can I know the name of the exception in C++?如何知道 C++ 中异常的名称?
【发布时间】:2011-03-08 00:50:46
【问题描述】:

使用 Python,我可以很容易地得到异常的名称,如下所示。

  1. 运行代码,即 x = 3/0 从 python 获取异常
  2. “ZeroDivisionError:整数除法或模除以零”告诉我这是 ZeroDivisionError
  3. 修改代码,即 try: x=3/0 except ZeroDivisionError: DO something

有没有类似的方法可以用 C++ 找到异常名称?

当我运行 x = 3/0 时,编译后的二进制文件只是抛出“浮点异常”,与 python 相比,这不是那么有用。

【问题讨论】:

  • 你不应该除以零 ;)
  • 确实;除以零将调用未定义的行为。在 Posix 平台上,它将引发 SIGFPE 而不是抛出 C++ 异常,因为这是 Posix 定义的行为。

标签: c++ python exception-handling


【解决方案1】:

虽然您不能轻易询问异常的名称,但如果异常源自std::exception,您可以通过what() 找出其显示的具体原因:

try
{
    ...
}
catch (const std::exception &exc)
{
    std::err << exc.what() << std::endl;
}

附带说明,除以 0 并不能保证引发 C++ 异常(我认为 MS 平台可能会这样做,但在 Linux 上你不会得到)。

【讨论】:

  • Win32 平台可以引发 SEH EXCEPTION_FLT_DIVIDE_BY_ZERO 异常 (0xC000008E)。还有一个整数变量,EXCEPTION_INT_DIVIDE_BY_ZERO == 0xC0000094
【解决方案2】:

如果您想知道异常类的名称,可以使用 RTTI。但是,绝大多数 C++ 代码都会抛出从 std::exception 派生的异常。

但是,您得到的只是 std::exception::what 中包含的异常数据,您可以从 RTTI 获取异常类的名称,并在需要更多信息时显式捕获它(并且它包含更多信息) .

【讨论】:

    【解决方案3】:

    对于大多数例外情况,如果您在编译器中设置了 RTTI 选项,您可以这样做:

    catch(std::exception & e)
    {
        cout << typeid(e).name();
    }
    

    不幸的是,除以零引发的异常不是从 std::exception 派生的,所以这个技巧将不起作用。

    【讨论】:

    • 还要注意 typeid(foo).name() 的格式是实现定义的;在某些平台上,它被破坏了。
    【解决方案4】:

    如果这是一个调试问题,您可以将编译器设置为在遇到异常时中断,这可能非常有用。

    【讨论】:

      猜你喜欢
      • 2017-08-09
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 2022-08-24
      • 2021-08-19
      • 2022-01-19
      • 1970-01-01
      相关资源
      最近更新 更多