2017-03-23 9 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であるd_selfsIntentsにfind(const OTC_String &の名前)を呼び出すと、d_selfsIntentsが初期化されていないため、コア・ダンプが発生します。

Matteoの質問に答えるには、はい、別の静的構造(f_en_route_to_escort)の初期化から静的構造(d_selfsIntents)にアクセスしようとしています。

もう一方が初期化される前に問題を参照してください。私が持っているかもしれない質問は、なぜこれが現在問題になっているのかです。彼の提案は、ずっと前に扱われていたはずのもののように聞こえる。私たちのコードには、このような数百の例があり、15年以上前から開発されてきましたが、今まで問題となったことはありません。

どのような順序、コンパイラ、またはリンカを設定しますか?ここで問題となる2つのコンパイル単位は、unitprot(unitprot_SelfsIntent)とutil(util_Registry)です。私たちは特定の順序でそれらをコンパイルしますが、問題はリンク時または実行時に発生していると思います。

は、あなたが他の静的データメンバーの初期化中または実行がすでにメイン入った後にこれらの静的データメンバにアクセスしてみてくださいかどうか、私は疑問から欠場
sglasgow

+0

グーグル*静的初期化順序の大失敗*。あなたはちょうど最初は幸運だったが、今運がなくなった。それが人生だ。 –

答えて

1

何かがある、ありがとうございます。

最初のケースでは、変数の静的な初期化は、異なるコンパイル単位で定義された順序とは関係なく、特定の順序で行われることが保証されていないことに注意してください。

改善が必要な場合がありますが、これを処理する通常の方法は、これらのメンバーのパブリックゲッターとして動作する静的メソッド内で初期化を行うことです。 Simplified、これはシングルトンパターンを使用することになります。

あなたの例では、ヘッダーに次のようになります。

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; 
} 
関連する問題