2017-04-17 22 views
2

다음 프로그램을 실행할 때 mangled 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> 20 단

, I 트리거하기 위해 truetest() 함수에 noexcept 사양을 변경할 때 std::terminate()에 전화하면 다음 출력이 표시됩니다.

의 libC++ abi.dylib : 나는 표준이 : (종료 생각 x>는 20

)이 있기 때문이라는 unmangled 유형을 제공 할 수 있습니다 유형 표준 : really_out_of_range의 캐치되지 않는 예외로 종료 명시 적으로 각 표준 예외 유형을 처리했지만 분명히 위에 정의 된 새 예외 유형을 올바르게 처리하므로 분명하지 않습니다.

내 질문에 왜 std::terminate() 올바른 typeinfo 이름이 있습니까?하지만 직접 액세스하려고 할 때? 또는 더 많은 요점은, 어떤 기능을 unmangled 클래스 이름을 제공하는 std::terminate() 호출합니까?

+1

내 생각에'std :: terminate'는 typeinfo 이름을 demangling합니다. 환경 - 내부 기능을 사용할 가능성이 있습니다. 예를 들어, G ++는'abi :: __ cxa_demangle'을 가지고 있습니다. – cdhowie

+0

'typeid (anything) .name()'의 결과는 구현에 따라 정의됩니다. 'std :: terminate()'는 demangle (또는 특정 형식의 예외 유형을 나타 내기 위해) 할 필요가 없으며, 이름을 빗 나갈 표준 함수가 없다. 마지막으로 네임 스페이스'std'에 선언을 추가하면 정의되지 않은 동작이 발생합니다. – Peter

답변

0

cdhowie의 코멘트 후, 여기에 답을 발견 Unmangling the result of std::type_info::name

기본적으로, 당신 #include <cxxabi.h> 당신은 GNU를 사용하는 경우 abi::__cxa_demangle를 호출합니다. 그러나 메모리 관리에주의를 기울여야합니다.

그러나 부스트 기능을 사용할 수도 있습니다. 그런 다음 #include <boost/core/demangle.hpp>으로 전화하여 boost::core::demangle(name)으로 전화하십시오.

.