静态库中的多重定义

Multiple definition within static library

我有一个与 密切相关的问题,但涉及的情况略有不同。 就像那里一样,我有两个 .cpp 文件(比如:test1.cpptest2.cpp),每个文件都包含相同功能的实现,即 void testfunc()。我还有一个头文件 test.h,我在其中声明 testfunc,还有一个文件 main.cpp,其主函数包含对 testfunc() 的调用,如下所示:

include "test.h"
int main() {
    testfunc();
}

我通过调用 g++ -c *.cpp 单独编译 .cpp 文件,然后使用 ar rvs libtest.a test1.o test2.o 从中创建一个静态库。现在将 main.o 链接到库时,链接器不会像我预期的那样抱怨:

gcc main.o -L. -ltest -o main

生成的可执行文件工作得非常好 - 调用 testfunc() 的两个实现之一。老实说,我预计会出现 multiple definition of... 之类的错误。因此,我的问题是:

  1. 为什么这实际上有效 - 是 ar 中的原因,它只将两个目标文件之一添加到库中,或者库是否包含两个目标文件 & 这种行为的原因是在链接过程中找到,链接器在找到 testfunc?
  2. 的一个定义后停止搜索库
  3. 我能以某种方式影响 testfunc 的哪个定义被实际使用,或者甚至被定义了吗?即,是否可能是 ar 的参数顺序决定使用哪一个?
  4. 此行为对于 ar 的任何 linker/version 是否相同,或者这可能取决于系统?

库只是包含导出符号的 object-files 的 collection。 它可能包含任意数量的重复(就像真实的图书馆可能包含许多具有相同标题的书一样)。不涉及链接。

链接时,一般来说,链接器只查看库以防有未解析的符号。 在寻找这些符号时,它可能会找到一个,如果找到了,它就不会再寻找那个符号了。

当它解析另一个 object 文件中发现的另一个未解析的符号时,可能会发生冲突,该文件包含较早发现的符号的定义;现在它会产生重复符号的错误。