当我使用 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