异常

时间:2017-04-17 12:48:28

标签: c++ exception-handling typeid typeinfo

当我运行以下程序时,我得到一个错误的typeinfo名称。

#include <iostream>
#include <stdexcept>
#include <typeinfo>

namespace std
{

class really_out_of_range
    : public out_of_range
{
public:
    explicit really_out_of_range(const string& __s) : out_of_range(__s) {}
    explicit really_out_of_range(const char* __s)   : out_of_range(__s) {}

    virtual ~really_out_of_range() _NOEXCEPT {}
};

}

void test () noexcept(false)
{
    throw std::really_out_of_range("x > 20");
}

int main () noexcept(true)
{
    try {
        test();
    } catch (const std::exception& e) {
        std::cout << "Exception caught: " << typeid(e).name() << ": " << e.what() << '\n';
    } catch (...) {
        std::cout << "Unknown exception caught\n";
    }
}

这是输出:

  

捕获异常:St19really_out_of_range:x&gt; 20

但是,当我将test()函数的noexcept规范更改为true以触发对std::terminate()的调用时,我得到此输出:

  

libc ++ abi.dylib:以未捕获的类型异常终止   std :: really_out_of_range:x&gt; 20

我认为std :: terminate()可能能够提供命名的unmangled类型,因为它显式处理了每个标准异常类型,但显然并非如此,因为它也正确处理了我在上面定义的新异常类型。

所以,我的问题是为什么std::terminate()中的typeinfo名称是正确的,但是当我尝试直接访问它时却没有?或者更重要的是,std::terminate()调用哪个函数提供一个未编组的类名?

1 个答案:

答案 0 :(得分:0)

the section of the HTML spec it links to发表评论后,我在这里找到了答案:cdhowie

基本上,如果您正在使用GNU,则#include <cxxabi.h>并致电abi::__cxa_demangle。但你必须小心内存管理。

但是,您也可以使用boost。然后,您只需#include <boost/core/demangle.hpp>并致电boost::core::demangle( name )