C++ 在链接 .o 和链接 .a 文件之间存在差异:不同的行为,为什么?
C++ differ between Linking with .o and with .a file: different behavior, why?
我预计:
linking with .o file, and linking with .a file archived from the .o file, should have no difference.
但事实并非如此。我有 2 个源文件,每个都声明 1class+1 static object+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”文件和链接从这 2 个“.o”文件归档的“.a”文件有什么区别。
为什么他们的行为不同?我在 rhel/ubuntu 上用 gcc/clang 进行了实验,结果都是一样的。我想知道是否有任何 C++ ABI 标准规定何时应该通过任何链接选项真正调用创建的 static/global 对象?
这种差异是怎么来的?
这是由于静态库的语义。如果链接器包含由命令行中它前面的某个目标文件引用的符号,则链接器将仅包含静态库中的文件(例如,main.cpp 引用来自 Second 的 f2,因此它被包含在内)。您可以使用
围绕您的库来覆盖此行为
-Wl,--whole-archive -lmystatic -Wl,--no-whole-archive
但这不是标准。
我预计:
linking with .o file, and linking with .a file archived from the .o file, should have no difference.
但事实并非如此。我有 2 个源文件,每个都声明 1class+1 static object+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”文件和链接从这 2 个“.o”文件归档的“.a”文件有什么区别。
为什么他们的行为不同?我在 rhel/ubuntu 上用 gcc/clang 进行了实验,结果都是一样的。我想知道是否有任何 C++ ABI 标准规定何时应该通过任何链接选项真正调用创建的 static/global 对象?
这种差异是怎么来的?
这是由于静态库的语义。如果链接器包含由命令行中它前面的某个目标文件引用的符号,则链接器将仅包含静态库中的文件(例如,main.cpp 引用来自 Second 的 f2,因此它被包含在内)。您可以使用
围绕您的库来覆盖此行为-Wl,--whole-archive -lmystatic -Wl,--no-whole-archive
但这不是标准。