链接与.o和.a文件之间的C ++有所不同:不同的行为,为什么?

时间:2016-12-28 15:08:03

标签: c++ static linker shared behavior

我期待:

  

与.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标准说明何时应该通过任何链接选项真正调用创建的静态/全局对象?

这种差异是如何产生的?

1 个答案:

答案 0 :(得分:2)

这是由于静态库的语义。链接器只包含来自静态库的文件,如果它包含由命令行中的某个目标文件引用的符号(例如main.cpp引用来自Second的f2,那么它包括在内)。您可以使用

覆盖您的库来覆盖此行为
-Wl,--whole-archive -lmystatic -Wl,--no-whole-archive

但这不是标准。

相关问题