我期待:
与.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的运行结果并没有构成“第一”的结果。对象,但是MyDirect会这样做。
(2)虽然&#39; Second&#39;始终构造对象。
我真的没有看到与2&#39; .o&#39;文件,并与&#39; .a&#39;归档于这些2&#39; .o&#39;文件。
为什么他们表现不一样?我在rhel / ubuntu上用gcc / clang进行了实验,都显示了相同的结果。我想知道是否有任何C ++ ABI标准说明何时应该通过任何链接选项真正调用创建的静态/全局对象?
这种差异是如何产生的?
答案 0 :(得分:2)
这是由于静态库的语义。链接器只包含来自静态库的文件,如果它包含由命令行中的某个目标文件引用的符号(例如main.cpp引用来自Second的f2,那么它包括在内)。您可以使用
覆盖您的库来覆盖此行为-Wl,--whole-archive -lmystatic -Wl,--no-whole-archive
但这不是标准。