多定义符号的C/ c++链接器顺序

C/C++ linker order for multiple defined symbols

本文关键字:c++ 链接 顺序 定义 定义符 符号      更新时间:2023-10-16

如果我在一个目标文件和一个库中定义了相同的符号,GNU链接器从目标文件中获取该符号。考虑这个例子:

g++ -L"dir/to/lib" -o Executable Test.o foo.o -lMyLib

如果我在foo.cpp和编译"MyLib"的源文件中定义了一个具有相同签名的函数foo,如果我使用这个顺序,GNU链接器总是倾向于前者。

这个行为是GNU工具链特定的吗?你知道其他的链接器也有同样的行为吗?这有任何文档记录(GNU文档,c++标准)吗?我找不到任何东西……

我想使用这个功能来替换/模拟某些功能,而做单元测试(又名链接缝)。

From http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html:

"链接器按照指定的顺序搜索和处理库和目标文件"

可能。

链接器如何处理给定的文件取决于链接器,但在你描述的确切情况下,我认为不会有是任何变化。当您指定一个对象文件时,它被包含在中在你的最终构建中,你会得到它所定义的任何符号;如果两个对象文件定义了相同的符号,通常会得到来自链接器的错误(但也有例外,由于弱符号或类似于fortran的数据定义处理)。图书馆是一个集合的目标文件;库的标准处理是用于链接器的扫描它,并合并任何对象(且仅包含那些对象)定义一个未定义的外部。如果对象文件在库只定义有问题的符号,并且它的定义具有已由显式指定的目标文件(链接器)解析不会将库中的目标文件合并到程序中。但是,如果库中的目标文件还定义了其他符号,其中一个解析了一个未定义的外部对象库中的文件将被合并到您的程序中所有它定义的符号。哪一个会导致多胞胎div定义。

从语言的角度来看,"链接顺序"是不确定的,不能以可靠的方式使用。

从平台(工具链)的角度来看,它必须以某种方式指定,并且-通常-它考虑所有未在对象中解析的符号的库和所有未在局部解析的符号的对象。这允许开发人员屏蔽/替换库函数。

现在,gcc(作为msvc)以与启动链接器的命令行相同的顺序进行链接。这种行为是否可以"信任"(也就是说,它将在未来的版本中得到维护)尚不清楚。(GCC文档使用现在时动词…)