c++ - 为什么不在这个静态库中创建多个已定义的符号?

标签 c++ linker linker-errors

在静态库项目中,我有一个头文件,其中包含已声明但未实现的函数。

我有一个实现这些功能的 .cpp 文件。

然后,为了更好地理解链接器错误,我复制了 cpp 文件,所以我有一个完全相同的拷贝,它也被编译了。因此,这两个文件的标题中的每个符号都有双重实现。

它编译,当在另一个项目中使用时,它链接。

这里是静态库的最小示例:

API.hpp:

void printWhatever();

errortest.cpp 和 duplicate.cpp 是相同的:

#include "api.hpp"
#include <iostream>
void printWhatever(){
  std::cout << "hi " << "\n";
}

我用这两个源文件将其编译为静态库。我看到编译器为这两个文件生成报告。

现在我在一个可执行文件中使用这个编译库,一个不同的项目: main.cpp :

#include <api.hpp>
int main(int argc, const char * argv[]) {
  printWhatever();

  return 0;
}

它运行并打印“hi”。

为什么函数没有多重定义?

最佳答案

添加到这个问题的关键事实是,具有重复符号的两个模块被链接到一个静态库

静态库与共享库的工作方式截然不同。链接时,链接器在静态库中搜索引用的符号。定义引用符号的第一个模块被链接以生成最终的可执行文件。另一个模块定义相同符号的事实无关紧要。如果具有重复符号的其他模块未定义可执行文件所需的任何其他符号,则它不会链接到可执行文件中。

如果您想看到静态库的重复错误:

main() 调用 foo()bar()

在静态库的第一个模块中定义foo()baz()

在静态库的第二个模块中定义bar()baz()

因为两个模块都包含从 main() 引用的符号,它们被迫与可执行文件链接,导致 baz() 出现重复符号错误。

关于c++ - 为什么不在这个静态库中创建多个已定义的符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37860582/

相关文章:

c - 优化C编译: removed unreferenced parts on-the-fly

c++ - "return"带有 & 运算符但没有指针的多个值 : How does this work?

c++ - 如何手动使另一个控件发出信号?

c++ - Windows 和 Linux (x86) 上的相同二进制代码

c - 部分链接到 C 中的动态链接

c++ - 我如何链接到 Ubuntu 上的 Qwt 库?

c++ - 无法使用 mingw32-g++ 链接 boost

c++ - Visual Studio 2013 错误 LNK2019

c++ - 从 friend 类调用析构函数

c++ - 为什么 C++ 允许将指向基对象的指针转换为派生类的指针