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?