C ++のグローバル初期化はどのように怠惰になることができますか?
-
11-09-2019 - |
質問
I)は、(メインの最初の行の前に起こっとしてグローバル/静的クラス・メンバーのすべての初期化の考え方に慣れています。しかし、私は最近、標準の初期化をするために、後に起こることを可能にすることをどこかで読ん「モジュールの動的ローディングを支援します。」私は図書館をdlopen'edする前に初期化するためのライブラリで初期化グローバルを期待していない:私は時に動的リンクこれが本当であること見ることができました。しかし、静的に一緒にリンク翻訳単位(私のアプリの直接の.oファイル)のグループ内私は、この動作は非常に直感見つけるだろう。これはのみのリンクか、それはいつでも起こる可能性が遅延したときに動的に発生しますか? (または私は間違って読んだものだった;?)
解決
標準は以下にしている3.6.2 / 3
これは、実装定義されている対象の動的初期化(8.5、9.4、12.1、12.6.1)か否かを判定する 名前空間スコープは、メインの最初の文の前に行われます。初期化は、いくつかのポイントに延期された場合 メインの最初の文の後の時間に、それは定義された任意の関数やオブジェクトを最初に使用する前に発生するもの 初期化するオブジェクトと同じ翻訳単位でます。
しかし、O はもちろん、あなたが変数にアクセスする前に初期化が発生しますので、初期化が行われ、を取るときは、など次の:は決して正式にを伝えることができます!
// t1.cc
#include <iostream>
int i1 = 0;
int main () {
std::cout << i1 << std::endl
// t2.cc
extern int i1;
int i2 = ++i1;
私はそれをg ++ 4.2.4は、少なくともメインの前に「I2」の初期化を実行するように見える準拠することができます。
他のヒント
一つは、そのルールに解決したかった問題は、動的ローディングの一つです。引当金は、動的ロードに限定されるものではなく、正式に他のケースのために発生する可能性があります。私は、動的ロードよりも何かのためにそれを使用して実装を知りません。
の疑似コードを確認してみましょう。
DLLでます:
static int ItsDllVar = 1;
int EXPORTED_FUNCTION() { return ItsDllVar; }
アプリケーションでます:
static int AppVar1 = 2;
static int AppVar2 = EXPORTED_FUNCTION() + AppVar1;
そこで静的初期化AppVar2に従って取得1 + 2 = 3
(かかわらず、DLLの)ローカル静的変数に適用可能な遅延初期化
int f()
{
static int local_i = 5;//it get's 5 only after visiting f()
return local_i;
}
私は、これはグラムで私の場合、何が起こったのかと思い++ 4.7およびCMakeの(これはCMakeの詳細については、関連あるかどうかわかりません)。私は、工場内の関数を登録するコードを持っています。これは、世界的に初期化された変数から呼び出すコンストラクタに依存しています。
このコードはを静的にリンクライブラリにあったときにの初期化は実現しませんでした!私は(すなわち、それらは最初のライブラリに統合されていない)に直接リンクされたオブジェクトファイルにそれを移動したとき、それは今、正常に動作してます。
だから、私はあなたが正しいことを疑います。