2017-04-17 50 views
2

當我運行以下程序時,我得到了一個損壞的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> 20

然而,當我爲了改變在test()功能noexcept規範true到觸發撥打std::terminate(),我得到這個輸出:

的libC++ abi.dylib:)X> 20

我認爲的std ::終止(也許能夠提供命名是因爲它的未重整類型:有型 的std :: really_out_of_range的未捕獲的異常終止明確地處理了每種標準異常類型,但顯然不是這種情況,因爲它也正確處理了我在上面定義的新異常類型。

所以,我的問題是爲什麼在std::terminate()中正確的typeinfo名稱,但不是當我嘗試直接訪問它時?或者,更重要的是,std::terminate()調用哪個函數提供了一個未加密的類名?

+1

我懷疑'std :: terminate'只是對typeinfo名稱進行了demangling。可能有一個它使用的環境內部函數。例如,G ++有'abi :: __ cxa_demangle'。 – cdhowie

+0

'typeid(anything).name()'的結果是實現定義的。 'std :: terminate()'不需要去掉(或者以任何特定的形式呈現一個異常的類型),並且沒有標準的函數來去除名字。最後,像名字空間'std'一樣添加聲明給出了未定義的行爲。 – Peter

回答

0

cdhowie「的評論後,我在這裏找到了答案:Unmangling the result of std::type_info::name

基本上,你#include <cxxabi.h>,如果你使用GNU叫abi::__cxa_demangle。但是你必須小心內存管理。

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