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

我期望:

linking with .o file, and linking with .a file archived from the .o file, should have no difference.

但事实并非如此.我有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) The running result of MylinkSta doesn’t construct ‘First’ object, but MyDirect does.

(2) While the ‘Second’ object is always constructed.

我真的没有看到链接2′.o’文件和链接到’.a’文件之间的任何区别,这些文件是从这些2′.o’文件存档的.

他们为什么表现不一样?我在rhel / ubuntu上用gcc / clang进行了实验,都显示了相同的结果.我想知道是否有任何C ABI标准说明何时应该通过任何链接选项真正调用创建的静态/全局对象?

这种差异是如何产生的?

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

-Wl,--whole-archive -lmystatic -Wl,--no-whole-archive

但这不是标准的.

点赞