问题描述
为什么下面的C++程序与系统提供的__cxa_throw
没有链接冲突?
#include <cstring>
void __cxa_throw(void *,void *,void (*)(void *)) {
std::puts("bad luck");
}
int main() {
throw 13;
}
那个符号有什么神奇之处吗?对于正常功能,这会违反 ODR,不是吗?
解决方法
正如@Igor 指出的,您需要添加 extern "C"
以防止名称修改。
但它起作用的原因是因为该符号很可能被定义为弱。这意味着如果您重新定义它,链接器将使用您的版本而不是标准库。
Gcc's source code 确认他们将其定义为弱。 我不确定原因,也许是与共享库的一些内部兼容性等等......
实际上,在我不知何故错过的定义上方有一条评论:
77 /* Everything from libstdc++ is weak,to avoid requiring that library
to be linked into plain C applications using libitm.so. */
这就是原因。
不言而喻,这样做真的很糟糕,甚至没有关于其他函数期望 __cxa_throw
做什么的适当文档。