静的ローカル変数は、最初の関数呼び出しで初期化されます。
static指定子を使用してブロックスコープで宣言された変数は、静的ストレージ期間を持ちますが、制御が最初に宣言を通過するときに初期化されます(初期化がゼロまたは定数初期化でない限り、ブロックが最初に入力される前に実行できます)。以降の呼び出しでは、宣言はスキップされます。
また、C ++ 11ではさらに多くのチェックがあります。
複数のスレッドが同じ静的ローカル変数を同時に初期化しようとした場合、初期化は1度だけ行われます(std :: call_onceを使用して任意の関数で同様の動作を取得できます)。注:この機能の通常の実装では、ダブルチェックされたロックパターンのバリアントを使用します。これにより、すでに初期化されたローカル静的のランタイムオーバーヘッドが1つの非アトミックブール比較に削減されます。(C ++ 11以降)
同時に、グローバル変数はプログラムの開始時に初期化されるようです(技術的には、割り当て / 割り当て解除のみがcppreferenceに記載されています)。
静的ストレージ期間。オブジェクトのストレージは、プログラムの開始時に割り当てられ、プログラムの終了時に割り当て解除されます。オブジェクトのインスタンスは1つだけ存在します。ネームスペーススコープで宣言されたすべてのオブジェクト(グローバルネームスペースを含む)には、この保存期間と、staticまたはexternで宣言されたオブジェクトがあります。
したがって、次の例を考えてみます。
struct A {
// complex type...
};
const A& f()
{
static A local{};
return local;
}
A global{};
const A& g()
{
return global;
}
f()
それが呼び出されるたびにその変数が初期化されたかどうかをチェックする必要があるため、それf()
よりも遅くなると仮定するのは正しいg()
ですか?
もちろんあなたは概念的に正しいですが、現代の建築はこれに対処できます。
最新のコンパイラーとアーキテクチャーは、パイプラインを調整して、すでに初期化されたブランチが想定されるようにします。したがって、初期化のオーバーヘッドにより、追加のパイプラインダンプが発生します。それだけです。
疑問がある場合は、アセンブリを確認してください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加