用的.o文件鏈接,並鏈接從.o文件將歸檔某文件,應該沒有差別。
但事實並非如此。我有2的源文件,每個文件聲明1class + 1的靜態對象+ 1個功能,以及調用的函數
$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
一個main.cpp的所以你可以看到
(1) MylinkSta的運行結果不會構建「第一個」對象,但MyDirect會執行此操作。
(2)雖然'Second'對象總是被構造的。
我真的沒有看到與2'.o'文件鏈接和鏈接'.a'文件與這兩個'.o'文件存檔的任何區別。
他們爲什麼表現不同?我在rhel/ubuntu上用gcc/clang進行了實驗,都顯示了相同的結果。我想知道是否有任何C++ ABI標準說明什麼時候應該真正調用創建的靜態/全局對象,通過任何鏈接選項?
這種差異是如何產生的?
鏈接器只會使用庫中的實際需要的對象文件來滿足某些外部引用;那些沒有以任何方式被引用的被忽略,全局變量和全部。大多數時候你都希望這樣 - 一個大的靜態庫通常包含比給定程序所需要的更多的代碼,你不希望整個事情與你的可執行文件鏈接,所以它最終包含了很多死了,從未使用過的代碼。 –