當我運行以下程序時,我得到了一個損壞的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()
調用哪個函數提供了一個未加密的類名?
我懷疑'std :: terminate'只是對typeinfo名稱進行了demangling。可能有一個它使用的環境內部函數。例如,G ++有'abi :: __ cxa_demangle'。 – cdhowie
'typeid(anything).name()'的結果是實現定義的。 'std :: terminate()'不需要去掉(或者以任何特定的形式呈現一個異常的類型),並且沒有標準的函數來去除名字。最後,像名字空間'std'一樣添加聲明給出了未定義的行爲。 – Peter