2011-06-11 19 views
1

我正在開發一個使用SourceryGpp lite for arm的應用程序和庫。ctor init不調用庫中的全局ctor實例

我沒有使用標準庫或默認啓動文件。 於是打電話給全球點擊率我做給下面的代碼:

ldr r0,=__ctors_init__ 
ldr r0,[r0] 
mov lr,pc 
bx r0 

所以問題是,我在靜態庫中定義一些全局實例,但它們的構建函數決不會被上面的代碼調用。奇怪的是,應用程序的全局成功被調用,任何人都知道爲什麼?

回答

5

這是一個衆所周知的問題,帶有運行時初始化的靜態庫和全局變量。

大多數連接器將只包含靜態庫的組件,這些組件需要執行主程序的依賴關係。如果編譯單元中沒有任何對象被使用,鏈接器 刪除 從不會增加作爲一個整體的編譯單元,並且不會發生全局初始化的副作用。

有一個很好的解釋here(最後的總結here

你將不得不使用標準庫提供的啓動代碼相同的問題。

+0

但是,有沒有解決這個問題沒有應用程序代碼引用靜態庫實例? – DVD 2011-06-11 20:12:55

+0

@DVD:Unity build解決了這個問題(因爲庫中只有一個編譯單元)。擺脫圖書館,只是通過命令行傳遞構成圖書館的所有文件效果良好。當然,您可以參考主程序中的變量,以便它們在鏈接時被拉入。 – 2011-06-11 20:38:33

+0

好吧thkz本和ybungalobill爲您的答覆 – DVD 2011-06-11 22:47:03

3

標準明確地允許推遲靜態對象初始化(C++ 98,[basic.start.init]):

它實現定義是否動態初始化(8.5,9.4, 12.1,12.6.1)的一個對象 命名空間作用域是在main的第一個語句之前完成的。如果初始化在main的第一條語句後及時推遲到某個點 ,它應該在與初始化的對象相同的翻譯單元中首次使用定義爲 的任何函數或對象之前發生。

(具有最新的C++ 0x草案有點不同的寫法。)

所以,如果你沒有不惜一切使用一些翻譯單元,所有的對象定義有可能被完全刪除。

+0

好點(+1),雖然他寫的代碼是延期將發生的地方,所以在他的情況下,沒有延期。初始化器不在全局初始化器列表中,因爲鏈接器沒有從庫中提取這些翻譯單元。 – 2011-06-11 19:10:58