【发布时间】:2013-03-30 07:50:39
【问题描述】:
std::exception.what() 及其派生类返回的 C 字符串的内容是实现定义的,但 clang、gcc 和 Visual Studio 返回指示异常类名称的 C 字符串。但是当我在 clang 3.2、gcc 4.7 和 Visual Studio 2012 上运行以下代码时,我得到了奇怪的结果:
#include <iostream>
#include <exception>
int main(int argc, const char * argv[])
{
try {
throw std::bad_alloc();
} catch (std::exception e) {
std::cout << e.what() << std::endl;
}
try {
throw std::bad_alloc();
} catch (std::bad_alloc e) {
std::cout << e.what() << std::endl;
}
return 0;
}
使用 clang 和 gcc 的输出是
std::exception
std::bad_alloc
VS11 的输出是
bad allocation
bad allocation
我的理解是 clang 和 gcc 实现了 exception::what() 之类的东西
const char* exception::what() const
{
return __typename_demangle(typeid(*this).name());
}
并且所有派生类都使用 what() 方法的这种实现。如果我在上面的代码中将 e.what() 替换为 typeid(e).name() 然后 clang 和 gcc 输出
St9exception
St9bad_alloc
和 VS11 输出
class std::exception
class std::bad_alloc
我不明白为什么两个 catch 块的 typeid 都不是 std::bad_alloc 。这种行为似乎会导致 what() 方法返回错误的值。 Microsoft 必须为从 std::exception 派生的所有类创建了不同的、简单的 what() 实现,因此 VS11 不会遇到这个问题。
【问题讨论】:
-
尝试通过引用捕获异常。
-
修复了它并回答了问题。通过按值捕获异常,我无意中将 std::bad_alloc 转换为 std::exception 并使其失去了 bad_allocness。有趣的是,VS11 在这两种情况下仍然设法返回“错误分配”。无论如何,如果你回答这个问题,我会接受它。
-
你看到的现象叫做“对象切片”。
标签: c++ exception-handling typeinfo