当我运行以下程序时,我得到了一个损坏的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