这里的Java人员坚持做一些c ++。我正在捕获异常并尝试诊断它的来源(遗憾的是,通过gdb运行时不会引发异常)。但是,当我打印出异常的what()时,我只需得到字符串" std :: exception"。这是否特定于标准库中的任何内容或许多标准异常返回此?以下是我要打印的内容:
} catch (const std::exception & ex) {
std::cout << ex.what() << std::endl;
}
输出只是:
std::exception
另外,我在一个相当大的代码库中工作,这可能是我们最终的一些例外,但我还没有通过常规搜索技术找到它,所以我目前倾向于来自标准库。
我使用g ++ 4.8,如果这是相关的。
答案 0 :(得分:14)
这可能是因为两件事:
有人在某处做throw std::exception()
,这不是很有帮助。
从std::exception
派生的类会被复制到std::exception
。这是一个名为Object Slicing的问题。
我实际上是自己犯了第二个错误。我有这个代码:
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 ++调试器应允许您在抛出任何异常时以及在捕获异常之前设置断点,以便在发生异常时通过调试器检查堆栈回溯。