【发布时间】:2016-12-28 15:08:02
【问题描述】:
我预计:
链接 .o 文件和链接 .o 文件存档的 .a 文件应该没有区别。
但事实并非如此。我有 2 个源文件,每个文件声明 1class+1 个静态对象+1 个函数,以及一个调用其中一个函数的 main.cpp
$cat First.cpp
#include<stdio.h>
struct First{
First(){printf("First\n");}
};
void f1(){printf("f1\n");}//Not called in main
static First f_obj;
$cat Second.cpp
#include<stdio.h>
struct Second{
Second(){printf("Second\n");}
};
void f2(){printf("f2\n");}//Not called in main
static Second s_obj;
$cat main.cpp
void f2();
int main()
{
f2();
return 0;
}
$g++ -c First.cpp -fPIC
$g++ -c Second.cpp -fPIC
$ar -rvs libmystatic.a First.o Second.o
$g++ main.cpp -o MylinkSta -lmystatic -L.
$g++ main.cpp -o MyDirect First.o Second.o
$./MylinkSta
Second
f2
$./MyDirect
Second
First
f2
所以你可以看到
(1) MylinkSta 的运行结果没有构造 'First' 对象,但 MyDirect 有。
(2) 虽然总是构造“第二”对象。
我真的看不出链接 2 个“.o”文件和链接从这 2 个“.o”文件存档的“.a”文件之间有什么区别。
为什么他们的行为不同?我在 rhel/ubuntu 上尝试了 gcc/clang,都显示了相同的结果。我想知道是否有任何 C++ ABI 标准规定何时应该通过任何链接选项真正调用创建的静态/全局对象?
这种差异是怎么来的?
【问题讨论】:
-
链接器只会使用库中的目标文件,这些文件实际上是满足某些外部引用所需要的;那些没有以任何方式引用的被忽略,全局变量和所有。大多数时候你都希望这样 - 一个大型静态库通常包含比给定程序所需的更多代码,你不希望整个东西与你的可执行文件链接,所以它最终包含很多死的,从未使用过的代码。
标签: c++ static linker shared behavior