web-dev-qa-db-ja.com

定数ローカル変数を静的(c ++)として定義するメリットはありますか?

void Animation::playAnimation() const
{
    static const int index = 0;
    const std::string& animationFileName = 
    m_animationContainer.getAnimationName(index);
    static const int zOrder = -1;
    static bool isLooping = false;

    AnimationBank::play(animationFileName,
                        zOrder,
                        isLooping);
}

定数ローカル変数をstaticとして定義するメリットはありますか?または、それは不必要であり、悪い習慣ですらあります。

9
T M

@Christopheの非常に良い答えを超えて、staticに対して生成されたコードはローカル変数のコードよりも悪い可能性が高いので、内部の利点に興味がある場合、staticsは最新のプロセッサではより悪いです。

その理由は、他のすべてのスレッドや他のすべての呼び出しによって見つけられるメモリ内のどこかに静的変数を配置する必要があるためです。これは基本的にそれらをグローバルメモリに置くことを意味します。

長年にわたり、プロセッサーとコンパイラーは、グローバル、静的、フィールドなどの他の変数と比較して、使用頻度が高いため、ローカル変数へのアクセスを大幅に最適化しています。コンパイラーは、ローカル変数をCPUレジスターに保管することを選択する場合があり、そうでない場合(したがって、代わりに呼び出しスタックを使用します)、スタックのすべてがほぼ確実にキャッシュにあります。スタックへのアクセスは、通常、(スタックポインタレジスタから離れた)短距離アドレッシングモードです。ただし、グローバルまたはスタティックにアクセスするには、通常、拡張オフセットまたは絶対アドレスが必要であるため、結果として得られる命令は、スタックメモリアクセスの同等の命令よりも長くなります。

そうは言っても、staticとconstの組み合わせにより、コンパイラーは使用時に定数値を置き換えることができることを検出する可能性があるため、おそらくconstを使用すると上記の問題が軽減されます。それでも、あなたのスニペットは少なくとも1つの非const静的を示しているので、おそらく議論はトピックです。

11
Erik Eidt

これはメリットの問題ではなく、セマンティクスの問題です。

  • 関数内の静的変数(メンバー関数を含む)は、変数がその関数のすべての呼び出し間で共有されることを意味します。そのため、その関数の1つの呼び出しは、後続の呼び出しに副作用があります。

  • 非静的変数は、関数の実行ごとに一意です。

したがって、特定の正当な理由で必要とされない限り、ローカル変数は非静的にしてください。

追加の注釈:静的変数も異なるスレッド間で共有されます。したがって、一度に複数のスレッドからこの関数を呼び出すと、競合状態とUBが発生する可能性があります(異なるオブジェクトに対して呼び出された場合でも)。

5
Christophe

ローカル変数は、関数が呼び出されるたびに初期化または構築されます。ローカル変数はスタックに格納されるため、通常はスレッドセーフです。

静的ローカル変数は、一度だけ初期化または構築されます。関数が初めて呼び出されたとき。ローカル静的変数はスタックに格納されないため、通常はスレッドセーフではありません。

Constローカル変数は変更されない変数であり、関数が呼び出されるたびに初期化または構築されます。ローカルconst変数はスタックに格納されるため、通常はスレッドセーフです。

静的constローカル変数は、変更されない変数であり、初期化または構築は1回だけです。関数が初めて呼び出されたとき。ローカル静的const変数はスタックに格納されないため、通常はスレッドセーフではありません。

コンパイラーは、const変数をコンパイル時定数に最適化できる場合があります。

コンパイラーは、スタックではなくレジスターにそれらを保持することにより、非静的変数を最適化できる場合があります。

0
Theron W Genaux