2017-03-23 121 views
0

我們正試圖從RHEL 6.7遷移到RHEL 7.3,並從gcc 4.4.7遷移到gcc 4.8.5。靜態變量未初始化

我們的靜態變量(在類定義之外初始化)都沒有初始化。例如,在文件unitprot_selfsintent.cc:

util_Registry<unitprot_SelfsIntent> * unitprot_SelfsIntent::d_selfsIntents = 
    new util_Registry<unitprot_SelfsIntent>(); 

d_selfsIntents聲明中unitprot_selfsintent.h靜態的。

util_Registry是一個模板類。我們第一次嘗試在這個註冊表中放置某些東西時,應用程序內核就會轉儲。 d_selfsIntents是一個0指針,尚未初始化。

我原以爲這會在我們嘗試在註冊表中放置某些東西之前就已經完成了。

一切正常,因爲它應該在舊的配置下。什麼可能已經改變,導致新的配置。是否有我需要調用的新編譯器選項?

更多信息...

另一類,unit_groundresunitc2.cc,具有已定義的靜態變量如下:

static unitprot_Selfintent * f_en_route_to_escort = 
    unitprot_SelfsIntent::registerObject("en_route_to_escort"); 

unitprot_SelfsIntent :: registerObject看起來是這樣的:

unitprot_SelfsIntent * unitprot_SelfsIntent::registerObject(const char * si) 
{ 
    OTC_String selfsIntent(si); 
    return registerObject(selfsIntent); 
} 

使用OTC_String調用registerObject如下:

unitprot_SelfsIntent * unitprot_SelfsIntent::registerObject(const OTC_String & si) 
{ 
    unitprot_SelfsIntent * regObj = d_selfsIntents->find(si); 

    if (regObj == 0) 
    { 
     regObj = new unitprot_SelfsIntent(si); 
     d_selfsIntents->registerObject(regObj); 
    } 

    return regObj; 
} 

在d_selfsIntents(它是util_Registry)上調用find(const OTC_String &名稱)會導致核心轉儲,因爲d_selfsIntents尚未初始化。

因此,要回答Matteo的問題,是的,我們試圖從另一個靜態構造(f_en_route_to_escort)的初始化中訪問靜態構造(d_selfsIntents)。

我看到使用一個之前,其他人被初始化的問題。我可能會遇到的問題是爲什麼現在這是一個問題?他的建議聽起來像是早就應該處理的事情。我們的代碼有數百個這樣的例子,並且已經開發了超過15年,直到現在從未成爲問題。

什麼設置順序,編譯器或鏈接器?這裏討論的兩個編譯單元是unitprot(用於unitprot_SelfsIntent)和util(用於util_Registry)。我們按特定順序編譯它們,但我認爲問題發生在鏈接時或運行時。

謝謝
sglasgow

+0

谷歌*靜態初始化順序的悲劇*。一開始你很幸運​​,但現在運氣已經用完了。這就是人生。 –

回答

1

我的東西從問題懷念的是你是否嘗試在其他靜態數據成員的初始化或執行已經進入主後訪問這些靜態數據成員。

如果是第一種情況,請注意,變量的靜態初始化不保證以任何特定順序發生,相對於在不同編譯單元中定義的順序。

可能有一些技巧可以改善這一點,但通常的處理方法是在靜態方法中完成初始化,這些靜態方法充當這些成員的公共getter。簡單來說,這相當於使用單例模式。然後

你的榜樣應該是這樣的標題:

class unitprot_SelfsIntent : ... 
{ 
public: 
    static util_Registry<unitprot_SelfsIntent>* GetSelfsIntents(); 
//... 
private: 
    static util_Registry<unitprot_SelfsIntent>* d_selfsIntents; 
//... 
}; 

以及實現這樣的:

util_Registry<unitprot_SelfsIntent>* unitprot_SelfsIntent::GetSelfsIntents() 
{ 
    // usually multithreading would be handled here 

    d_selfsIntents = new util_Registry<unitprot_SelfsIntent>(); 

    // some more synchronization 

    return d_selfsIntents; 
}