当我使用 STL 在 Linux 上编译 C++ 程序时,STL 库是如何链接的



当我使用 g++ 编译使用 STL 的程序时,该库如何链接到我的程序?动态还是静态?

静态对我来说听起来很奇怪,因为这意味着每个使用 STL 的C++程序都必须在内部包含它。另一方面,动态链接对我来说听起来也很奇怪,因为对于所有 OOP 的东西,我看不出库如何动态链接并支持不同类型的对象......

那么这里到底发生了什么?

答案在您的问题中:STL代表"标准模板库"。 由于模板位于头文件中,并且仅在需要时(例如使用)时才实例化,因此您可以包含每个 STL 标头(如果需要),如果您没有使用其中任何一个,您的二进制文件也不会更大。

STL 不是必须链接的 .lib 或 .a 文件。 它是头文件的集合。

模板始终根据需要实例化,并且针对它们使用的对象定制的实例是生成的二进制文件的一部分。

不基于模板的 STL 的其余部分可以静态或动态链接,具体取决于编译器设置。

部分动态,部分静态:

  • 静态链接所有模板实例化(显式或隐式)
  • 其他内容动态链接

这个简单的例子:

#include <vector>
int main()
{
    std::vector<int> v;
}

编译成

 g++  xxx.cpp -g  -Wall -Wextra

生成一个链接下一个库的文件:

$ ldd a.out 
        linux-vdso.so.1 =>  (0x00007fffa7767000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f353bee7000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f353bcd1000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f353b908000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f353b604000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f353c20c000)

它有矢量符号:

$ nm a.out | grep vector
000000000040073e W _ZNSt6vectorIiSaIiEEC1Ev
000000000040073e W _ZNSt6vectorIiSaIiEEC2Ev
0000000000400758 W _ZNSt6vectorIiSaIiEED1Ev
0000000000400758 W _ZNSt6vectorIiSaIiEED2Ev

最新更新