std::exception. .()在clang和gcc上返回意外值,但在VS11上没有
std::exception.what() returns unexpected value on clang and gcc, but not on VS11
std::exception. .()及其派生类返回的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()方法返回错误的值。微软一定已经为所有从std::exception派生的类创建了不同的、琐碎的what()实现,所以VS11不会受到这个问题的困扰。
您得到这个输出是因为在第一种情况下您创建了一个新的std::exception
对象,而在第二种情况下创建了一个新的std::bad_alloc
对象。相反,你应该通过引用来捕获异常。下面的代码将显示两者的区别:
#include <iostream>
#include <string>
class Foo
{
public:
Foo()
{
// std::cout << "Foo()" << std::endl;
}
Foo(const Foo&)
{
std::cout << "Foo(const Foo&)" << std::endl;
}
virtual ~Foo()
{
}
virtual std::string what() const
{
return "what: Foo";
}
};
class Bar: public Foo
{
public:
Bar()
{
// std::cout << "Bar()" << std::endl;
}
Bar(const Bar&)
{
std::cout << "Bar(const Bar&)" << std::endl;
}
std::string what() const
{
return "what: Bar";
}
};
int main()
{
try
{
throw Bar();
}
catch(Foo f)
{
std::cout << f.what() << std::endl;
}
try
{
throw Bar();
}
catch(const Foo& f)
{
std::cout << f.what() << std::endl;
}
return 0;
}
输出为
Foo(const Foo&)
what: Foo
what: Bar
但是我没有VS11,所以我不能告诉你,为什么VS会产生这样的输出。如果有人能澄清一下就太好了。
感谢@BoPersson:
OP中不同的消息是因为vc++实现了What()通过将消息文本存储在异常基类中。其他
相关文章:
- 在C++中对T*类型执行std::move的意外行为
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 处理除以零会导致<csignal>意外行为
- vscode下的Arduino代码出现意外编译错误
- 使用++运算符会导致意外的结果
- 套接字读取后,我在缓冲区中看到意外输入
- 更改.cpp程序的输入文件中数据的位置会意外更改输出
- 使用vscode调试时,GDB意外退出
- 此测试()中发生了什么意外过程?为什么总是覆盖 ch[0 1 2..]?
- 尝试将字符串/字符转换为整数会产生意外结果
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- C++标头错误 C2238 意外标记";"
- C++中意外的多头值
- vector.size() 在比较中意外工作
- 使用 malloc() 时出现意外大小
- 多线程程序中出现意外的内存泄漏
- 为什么static_cast基础类型的枚举类int8_t获得意外值?
- 字符串比较中的意外输出
- 我的代码中的意外价值以及我如何修复它
- std::exception. .()在clang和gcc上返回意外值,但在VS11上没有