2

When I run the following program, I get a mangled typeinfo name.

#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";
    }
}

Here is the output:

Exception caught: St19really_out_of_range: x > 20

However, when I change the noexcept specification on the test() function to true in order to trigger a call to std::terminate(), I get this output:

libc++abi.dylib: terminating with uncaught exception of type std::really_out_of_range: x > 20

I thought that std::terminate() might be able to provide the unmangled type named because it explicitly handled each standard exception type, but that's clearly not the case because it also correctly handles the new exception type that I defined above.

So, my question is why is the typeinfo name correct in std::terminate(), but not when I try to access it directly? Or, more to the point, what function does std::terminate() call that provides an unmangled class name?

IntellectualKitty
  • 523
  • 1
  • 6
  • 12
  • 1
    My suspicion is that `std::terminate` is just demangling the typeinfo name. There is likely an environment-internal function that it uses. For example, G++ has `abi::__cxa_demangle`. – cdhowie Apr 17 '17 at 12:56
  • The result of `typeid(anything).name()` is implementation defined. `std::terminate()` is not required to demangle (or to present the type of an exception in any particular form), and there is no standard function to demangle a name. Lastly, adding declarations to namespace `std` as you have gives undefined behaviour. – Peter Apr 17 '17 at 14:02

1 Answers1

0

After cdhowie's comment, I found the answer here: Unmangling the result of std::type_info::name

Basically, you #include <cxxabi.h> and call abi::__cxa_demangle if you're using GNU. But you have to be careful with the memory management.

However, you can also use boost. Then you just #include <boost/core/demangle.hpp> and call boost::core::demangle( name ).

.

Community
  • 1
  • 1
IntellectualKitty
  • 523
  • 1
  • 6
  • 12