为什么定义 `__cxa_throw` 不会导致 link 错误?

Why doesn't defining `__cxa_throw` cause a link error?

为什么下面的C++程序与系统提供的__cxa_throw没有link冲突?

#include <cstring>

void __cxa_throw(void *, void *, void (*)(void *)) {
    std::puts("bad luck");
}

int main() {
    throw 13;
}

那个符号有什么神奇之处吗?对于正常功能,这会违反 ODR,不是吗?

正如@Igor 指出的那样,您需要添加 extern "C" 以防止名称混淆。

但它起作用的原因是因为该符号很可能被定义为 weak。这意味着如果您重新定义它,链接器将使用您的版本而不是标准库。

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 做什么的适当文档。