全域性變數鏈結順序問題

2021-08-21 12:09:40 字數 1874 閱讀 6977

最近同事專案中遇到乙個問題,就是在main函式未啟動之前,就出現崩潰。具體現場情況大致是使用了乙個map,但這個map的insert操作直接導致崩潰。最終定位的原因,是map的定義是放到了另乙個編繹單元之中,而使用map的時候,該map物件還未進行初始化。這是全域性變數的初始化順序問題,即是用到某個變數的時候,它其實還未初始化。

知識點:

1、全域性變數的初始化,是在main函式之前。

2、不同編繹單元的全域性變數,初始化有先後順序之分。

下面看兩段**即可比較明確該問題

test1.cpp

#include

#include

usingnamespacestd;

classtest1

};

test1 obj_test1;

test2.cpp

#include

#include

usingnamespacestd;

classtest2

};

test2 test2;

intmain(intargc,char** argv)

makefile

target=main

objs=test1.o test2.o

$(target):$(objs)

g++ -o main test1.o test2.o

#g++ -o main test2.o test1.o

%.o:%.cpp

g++ -c $<

clean:

rm $(target) -f

rm $(objs) -f

注意最後的鏈結命令,這裡生成main的時候,即可以用g++ -o main test1.o test2.o,也可以使用g++ -o main test2.o test1.o,大多數情況下, 這樣對結果是沒有什麼區別。但在這個問題上,是有很大區別。

g++ -o main test1.o test2.o,這樣是test2這個類先構造 ,g++ -o main test2.o test1.o,這樣則是test1這位類先構造 。大家可以自行修改鏈結順序觀察初始化順序。

對於類的初始化過程,如果需要使用的其他類物件,是定義到其他編繹單元的時候,則可能遇到這種初始化順序的問題。一般來說,有如下幾種解決方案:

2、將變數定義到乙個編繹單元之中,這樣就直接規避了這個問題。如果實在無法用這種方式的時候,推薦使用第3種。

3、採用函式構造,不直接使用變數。通過主動觸發乙個函式返回乙個物件,在函式對主動觸發物件的構造,例如在函式中去new乙個物件出來。

static全域性變數 全域性變數

1 全域性變數 外部變數 的說明之前再冠以static 就構成了靜態的全域性變數。全域性變數本身就是靜態儲存方式,靜態全域性變數當然也是靜態儲存方式。這兩者在儲存方式上並無不同。這兩者的區別在於非靜態全域性變數的作用域是整個源程式,當乙個源程式由多個原始檔組成時,非靜態的全域性變數在各個原始檔中都是...

全域性變數的問題

今天在工程裡新增了乙個專門放置全域性變數的標頭檔案,在別的很多c檔案中進行了引用,沒想到編譯的時候老是提示duplicate symbal g7task.說來自己也太差勁了,竟然忘了在c檔案中新增extern關鍵字來引用這個外部變數。而且要命的是在標頭檔案中是不能賦初值的,否則會遇到同樣的鏈結錯誤。...

php 全域性變數問題

當在函式裡通過require once包含另外php檔案。而另外php檔案包含了另外php檔案,而該php檔案的函式需要另外的php檔案。例子 installment maintenance submit.php檔案裡downloadzip函式在內部包含了reboottipsfunc.php fun...