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 はこの問題に悩まされません。