静态库中的多个定义

Multiple definition within static library

本文关键字:定义 静态      更新时间:2023-10-16

我有一个与链接器密切相关的问题,当相同的符号在对象文件和静态库中共存时,它不会发出多个定义错误,但涉及的情况略有不同。 就像那里一样,我有两个.cpp文件(例如:test1.cpptest2.cpp(,每个文件都包含相同功能的实现,即void testfunc().我还有一个头文件test.h我在其中声明testfunc,以及一个带有 main 函数的文件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. 我能否以某种方式影响实际使用testfunc的定义,或者甚至是否定义了这个定义? 即,在决定使用哪一个ar可能是参数的顺序吗?
  3. 对于任何链接器/版本的ar,此行为是否相同,或者这可能取决于系统?

库只是包含导出符号的对象文件的集合。 它可能包含任意数量的重复项(就像真正的图书库可能包含许多具有相同标题的书籍一样(。不涉及任何链接。

链接时,一般来说,链接器仅在存在未解析的符号时查看库。 在寻找这些符号时,它可能会找到一个,如果它这样做,它将不再寻找该符号。

当它解析在另一个对象文件中找到的另一个未解析的符号时,可能会出现冲突,该文件包含先前找到的符号的定义;现在它将生成重复符号的错误。