std::exception's what() 返回"std::exception"

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

本文关键字:std exception 返回 what      更新时间:2023-10-16

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

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

输出只是:

std::exception

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

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

这可能是因为两件事:

  1. 有些人只是在某个地方做throw std::exception(),这并没有多大帮助。

  2. std::exception派生的类被复制到std::exception。这是一个称为对象切片的问题。

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

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

您必须确保执行std::exception& e。我知道你没有犯这个错误,但可能是其他人在代码中做得更远(或者是谷歌的人)。

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

C++标准规定what()返回的字符串是完全任意的,并且实现定义为:

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.

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

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

话虽如此:许多C++实现将为您提供一些特定于实现的机制,以便尽运行库的最大能力转储当前堆栈回溯。有关详细信息,请查看C++编译器的文档。

例如,gcc提供了backtrace(),以及一些gcc内部函数,用于将backtrace)返回的原始地址转换为符号,以及其他用于对符号进行解映射的函数。使用它,可以大致模拟Java的异常处理;尽管gcc的实现并不完美,并且有一些功能漏洞,这也需要预先规划,以及自定义异常类,这些异常类的构造函数捕获当前堆栈帧(在实际抛出异常之前);并且,一旦被捕获,就可以检查抛出的异常类实例中捕获的回溯信息。

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