std :: exception's what()返回“std :: exception”

时间:2015-02-17 02:13:46

标签: c++ exception stl

这里的Java人员坚持做一些c ++。我正在捕获异常并尝试诊断它的来源(遗憾的是,通过gdb运行时不会引发异常)。但是,当我打印出异常的what()时,我只需得到字符串" std :: exception"。这是否特定于标准库中的任何内容或许多标准异常返回此?以下是我要打印的内容:

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

输出只是:

std::exception

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

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

2 个答案:

答案 0 :(得分:14)

这可能是因为两件事:

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

  2. std::exception派生的类会被复制到std::exception。这是一个名为Object Slicing的问题。

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

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

    您必须确保std::exception& e。我知道你没有犯这个错误但是其他人可能会在代码中做更多的事情(或者来自谷歌的人)。

答案 1 :(得分:5)

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.

您获得的返回值,&#34; std :: exception&#34;完全符合C ++标准。

不要依赖C ++异常来告诉你在捕获它们之后它们的确切位置,就像Java那样。这超出了C ++标准的范围。在C ++中,异常实际上只是一种传输执行控制流的机制。

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

例如,gcc提供了backtrace(),以及一些gcc内部函数,用于将backtrace()返回的原始地址转换为符号,以及用于解码符号的其他函数。使用它,可以编写一个粗略的类似于Java的异常处理;虽然gcc的实现并不完美,并且有一些功能漏洞,并且还需要提前规划,以及自定义异常类,其构造函数捕获当前堆栈帧(之前异常获取实际上扔了);并且,一旦捕获,就可以检查抛出的异常类实例以获取捕获的回溯信息。

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