模板化C++对象文件

Chr*_*ris 9 c++ templates g++ ld

假设我有两个.cpp文件,file1.cpp和file2.cpp,它们都使用std::vector<int>.假设file1.cpp有一个int main(void).如果我将两者编译成file1.o和file2.o,并将两个目标文件链接到我可以执行的elf二进制文件中.我正在编译32位Ubuntu Linux机器.

我的问题是关于编译器和链接器如何将std :: vector的符号放在一起:

  • 当链接器生成我的最终二进制文件时,是否存在代码重复?链接器是否有一组"模板化"代码用于f1.o中使用std::vectorstd::vector代码和另一组代码用于包含f2.o的代码?

我为自己尝试了这个(我用过g++ -g),然后我查看了我的最终可执行文件反汇编,我发现为向量构造函数和其他方法生成的标签显然是随机的,尽管来自f1.o的代码似乎调用了相同的构造函数.来自f2.o的代码.但是,我无法确定.

如果链接器确实阻止了代码重复,它是如何做到的?它必须"知道"什么模板?它是否始终阻止关于跨多个目标文件多次使用相同模板化代码的代码重复?

lit*_*adv 9

它通过名称修改知道模板是什么.对象的类型由编译器在其名称中编码,并允许链接器过滤掉同一模板的重复实现.

这是在链接期间完成的,而不是编译,因为每个.o文件都可以与任何东西链接,因此不能剥离以后可能需要的东西.只有链接器可以决定哪些代码未使用,哪个模板是重复的等等.这是通过在对象的符号列表中使用" 弱符号 "来完成的:如果链接器多次出现,链接器可以删除的符号(与其他符号相反,与用户定义的函数一样,如果重复则无法删除并导致链接错误).