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

问题描述

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...