C/C++ 全局變量初始化

C語言全局變量只能用常量表達式初始化,不能用一個數學函數或者其他的需要在運行時才能計算出結果的表達式進行初始化。

C++ 標準,全局變量的初始化要在 main 函數執行前完成,常識無疑,但是這個說法有點含糊,main 函數執行前到底具體是什麼時候呢?是編譯時還是運行時?答案是既有編譯時,也可能會有運行時(seriously), 從語言的層面來說,全局變量的初始化可以劃分爲以下兩個階段(c++11 N3690 3.6.2):

  • static initialization: 靜態初始化指的是用常量來對變量進行初始化,主要包括 zero initialization 和 const initialization,靜態初始化在程序加載的過程中完成,對簡單類型(內建類型,POD等)來說,從具體實現上看,zero initialization 的變量會被保存在 bss 段,const initialization 的變量則放在 data 段內,程序加載即可完成初始化,這和 c 語言裏的全局變量初始化基本是一致的。

  • dynamic initialization:動態初始化主要是指需要經過函數調用才能完成的初始化,比如說:int a = foo(),或者是複雜類型(類)的初始化(需要調用構造函數)等。這些變量的初始化會在 main 函數執行前由運行時調用相應的代碼從而得以進行(函數內的 static 變量除外)。

需要明確的是:靜態初始化執行先於動態初始化! 只有當所有靜態初始化執行完畢,動態初始化纔會執行。顯然,這樣的設計是很直觀的,能靜態初始化的變量,它的初始值都是在編譯時就能確定,因此可以直接 hard code 到生成的代碼裏,而動態初始化需要在運行時執行相應的動作才能進行,因此,靜態初始化先於動態初始化是必然的。

對於出現在同一個編譯單元內的全局變量來說,它們初始化的順序與他們聲明的順序是一致的(銷燬的順序則反過來),而對於不同編譯單元間的全局變量,c++ 標準並沒有明確規定它們之間的初始化(銷燬)順序應該怎樣,因此實現上完全由編譯器自己決定,一個比較普遍的認識是:不同編譯單元間的全局變量的初始化順序是不固定的,哪怕對同一個編譯器,同一份代碼來說,任意兩次編譯的結果都有可能不一樣。

發佈了55 篇原創文章 · 獲贊 3 · 訪問量 6617
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章