1. ホーム
  2. c++

[解決済み] C++の関数内のスタティック変数のライフタイムは?

2022-03-22 04:41:05

質問

という変数が宣言されている場合 static は一度だけ初期化され、関数が呼び出されるたびにその値を保持します。その寿命とはいったい何でしょうか?また、コンストラクタやデストラクタはいつ呼び出されるのでしょうか?

void foo() 
{ 
    static string plonk = "When will I die?";
}

解決方法は?

関数の寿命 static 変数が開始されるのは [0] は、プログラムの流れがその宣言に遭遇し、プログラムの終了時に終了します。つまり、ランタイムは、実際に構築された場合のみ、それを破棄するために、何らかのブックキーピングを行わなければならない。

さらに、静的オブジェクトのデストラクタは、その構築の完了と逆の順序で実行されなければならないと規格で定められているので [1] であり、具体的なプログラムの実行順序に依存する可能性があるため、構築順序を考慮する必要があります。

struct emitter {
    string str;
    emitter(const string& s) : str(s) { cout << "Created " << str << endl; }
    ~emitter() { cout << "Destroyed " << str << endl; }
};

void foo(bool skip_first) 
{
    if (!skip_first)
        static emitter a("in if");
    static emitter b("in foo");
}

int main(int argc, char*[])
{
    foo(argc != 2);
    if (argc == 3)
        foo(false);
}

出力します。

C:>sample.exe
fooで作成された
fooで破壊された

C:>sample.exe 1
で作成されます。
fooで作成
fooで破壊された
if で破壊される

C:>sample.exe 1 2
fooで作成された
if で作成された
ifで破棄される
foo で破壊される

[0] 以来 C++98 [2] はマルチスレッドへの言及がなく、マルチスレッド環境でどのように動作するかは未定であり、以下のような問題があります。 ロディ が言及しています。

[1] C++98 セクション 3.6.3.1 [基本.開始.項]。

[2] C++11では、静的要素はスレッドセーフな方法で初期化され、これは次のように知られています。 マジックスタティック .