std::exception 是什么() returns "std::exception"

std::exception's what() returns "std::exception"

Java 这里的人一直在做一些 C++。我正在捕获一个异常并试图诊断它来自哪里(遗憾的是当 运行 通过 gdb 时没有抛出异常)。但是,当我打印出异常的 what() 时,我只是得到了字符串 "std::exception"。这是特定于标准库中的任何东西还是做很多标准异常 return 这个?这是我要打印的内容:

    } catch (const std::exception & ex) {
      std::cout << ex.what() << std::endl;
    }

输出只是:

std::exception

另外,我在一个相当大的代码库中工作,这可能是我们这边的一些异常,但我还没有通过常规搜索技术找到它,所以我目前倾向于这来自标准库。

如果相关的话,我正在使用 g++ 4.8。

C++ 异常与 Java 异常完全不同。

C++ 标准指定由 what() 编辑的字符串 return 是完全任意的,并且是实现定义的:

virtual const char* what() const noexcept;

Returns: An implementation-defined ntbs.
Remarks: The message may be a null-terminated multibyte string
(17.5.2.1.4.2), suitable for conversion
and display as a wstring (21.3, 22.4.1.4). The return value remains 
valid until the exception object
from which it is obtained is destroyed or a non-const member
function of the exception object is called.

您得到的 return 值 "std::exception" 完全符合 C++ 标准。

不要像 Java 那样依赖 C++ 异常来告诉您它们在捕获后从何处抛出。这超出了 C++ 标准的范围。在C++中,异常实际上只不过是一种传递执行控制流的机制。

话虽如此:许多 C++ 实现将为您提供一些特定于实现的机制来转储当前堆栈回溯,以发挥运行时库的最佳能力。查看 C++ 编译器的文档以获取更多信息。

例如,

gcc 提供了 backtrace() 以及一些 gcc 内部函数以将由 backtrace() 编辑的原始地址 return 转换为符号,以及其他用于分解符号的函数。使用它,可以粗略地模拟 Java 的异常处理;虽然 gcc 的实现并不完美,并且有一些功能漏洞,这也需要提前计划,以及构造函数捕获当前堆栈帧的自定义异常 classes (before the实际上抛出异常);并且,一旦被捕获,就可以检查抛出的异常 class 实例以获取捕获的回溯信息。

但这并不能真正帮助您目前的情况。我建议您按照我的建议检查 C++ 编译器的文档,并调查调试器的功能。 C++ 调试器应该允许您在抛出任何异常时以及在捕获异常之前设置断点,以便您可以在异常发生时通过调试器检查堆栈回溯。

这可能是因为两件事:

  1. 有人只是在某处做了throw std::exception(),这不是很有帮助。

  2. std::exception 派生的 class 被复制到 std::exception。这是一个叫做Object Slicing.

  3. 的问题

实际上我自己犯了第二个错误。我有这个代码:

try
{
    // Some Boost stuff
}
catch (std::exception e)
{
    cerr << e.what() << endl;
}

您必须确保std::exception& e。我知道你没有犯这个错误,但有可能其他人在代码中做了更进一步的事情(或者来自 Google 的人)。