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 不会遇到这个问题。