【发布时间】:2014-08-26 16:11:31
【问题描述】:
我想用我自己的覆盖纯虚拟调用 (__cxa_pure_virtual()) 的标准处理程序。 Windows 的答案是“_set_purecall_handler()”。
Linux/GNU 中有类似的工具吗?
【问题讨论】:
我想用我自己的覆盖纯虚拟调用 (__cxa_pure_virtual()) 的标准处理程序。 Windows 的答案是“_set_purecall_handler()”。
Linux/GNU 中有类似的工具吗?
【问题讨论】:
你差一点就自己回答了这个问题。这是gcc/libstdc++-v3/libsupc++/pure.cc中__cxa_pure_virtual的来源:
extern "C" void
__cxxabiv1::__cxa_pure_virtual (void)
{
writestr ("pure virtual method called\n");
std::terminate ();
}
因此,没有直接等同于 Microsoft 的 _set_purecall_handler 与 GCC。但是,由于此函数调用了std::terminate,因此您可以使用std::set_terminate 设置一个处理程序,该处理程序在打印消息后被调用。
另一种可能的解决方案是提供您自己的__cxxabiv1::__cxa_pure_virtual 定义,它会覆盖库函数。像这样的:
namespace __cxxabiv1 {
extern "C" void
__cxa_pure_virtual(void) {
char const msg[] = "my pure virutal\n";
write(2, msg, sizeof msg - 1);
std::terminate();
}
}
【讨论】:
std::set_terminate() 是(足够接近的)答案!
_set_purecall_handler 不违反 ODR,因此即使它不可移植,但定义明确。我试图重新定义__cxa_pure_virtual,但我没有收到任何链接器错误,而且它是我自己的,所以它必须是一个弱符号,但nm将它列为T,奇怪。
如果不启用任何额外的警告,g++(4.5 测试)将告诉您您正在从构造函数/析构函数调用抽象函数,这应该消除设置自定义处理程序的任何需要。
由于有效的 C++ 程序永远不会导致纯虚拟调用,我假设您在 Windows 上设置了此处理程序用于诊断/调试目的。在这种情况下,在编译时而不是运行时进行诊断似乎要容易得多。
【讨论】:
__cxa_pure_virtual() 被调用时)。
#5 0x4015b7f4 in __cxxabiv1::__cxa_pure_virtual () at XXXX/src/gcc/libstdc++-v3/libsupc++/pure.cc:55