1

C++ の変数スコープについて読んでいて、興味深いブロック構造に遭遇しました。

int main(int argc, char **argv) {
    int local;

    { // New level of scope
        int more_local;
    }

    return 0;
}

閉じ中かっこ で示される各ブロックの最後で、スタックから変数がポップアウトされることを理解しています}

また、関数呼び出しも変数をスタックにプッシュし、中括弧を閉じることで示される呼び出しの最後で終了することも読みました}

void foo() {
    int more_local;
}

int main(int argc, char **argv) {
    int local;
    foo();

    return 0;
}

スタックは両方の状況でどのように異なる方法で処理され、両方の長所と短所は何ですか?

4

5 に答える 5

4

関数呼び出しを使用して、戻りアドレスをスタックにプッシュし、新しいスタック フレームを作成しています。あなたが言ったように、コードの一部を中括弧で囲むだけでは、新しいスコープを定義しています。それらは、if、for、while などの制御ステートメントに続くコードのブロックとまったく同じです。

長所と短所はまったく別のものなので、ここで語ることはできません。コードのブロックを中かっこで囲むことでメリットが得られる状況はほとんどなく、コードが読みにくくなる可能性があります。

于 2011-05-10T00:57:37.933 に答える
2

最初の例は、インライン関数と見なすことができると言えます。:P
しかし、一般的に、関数呼び出しと新しいものを開くscopeことは、互いに何の関係もありません。
関数を呼び出すと、戻りアドレスとすべての引数がスタックにプッシュされ、関数が戻った後にスタックからポップされます。
new を開くときはscope、スコープの最後でそのスコープ内のすべてのオブジェクトのデストラクタを呼び出すだけです。これらの変数によって占有されている実際のスペースがスタックからすぐにポップされることは決して保証されません。それは可能ですが、コンパイラ/オプティマイザの気まぐれに応じて、スペースは関数内の他の変数によって単純に再利用される可能性があります。

于 2011-05-10T00:50:34.803 に答える
1
  • ローカルスコープは引き続き他のローカル変数にアクセスできますが、関数には、使用する必要がある呼び出し元の変数を明示的に渡す必要があります

    • 変数を渡すのは面倒ですが、スコープ操作に実際に必要な変数のより小さなセットを明確に示すことで、コードがより理解しやすくなる場合があります (適切な関数名とコンテキスト関連が与えられた場合、操作を個別の機能単位にグループ化することを奨励するだけでなく)パラメーター名、およびそれらは再利用の準備ができています)
  • アウトオブライン関数呼び出しには、他にもいくつかのスタック スペースとパフォーマンス オーバーヘッドがあります: 戻りアドレス、保存されたレジスタ、呼び出しと戻り命令

  • 関数スコープと比較して、ローカル スコープは、大量のメモリ、スレッド、ファイル記述子、および/またはロックなどの重要なリソースを保持する変数のスコープを最小限に抑えるのに特に適しています。すぐに掃除することかもしれません

    • 変数の有効期間が短縮されると、プログラマーがコードを理解して維持するために頭の中で「追跡」しなければならない並行変数の数も減ります。
  • 一連の同様の操作を行っているときに、任意の異なる識別子を選択する必要があるのはあまり意味がない場合があるため、一部のローカルスコープでは、識別子を便利に「リサイクル」できます。

  • ローカルスコープは少しぎこちなく、ソースコードで「画面スペース」を取り、インデントレベルを増やします。そのため、「できる限り」ベースではなく、特定の正当な理由がある場合に使用することをお勧めします

于 2011-05-10T01:15:32.893 に答える
0

両方のプログラムのアセンブリ コードを観察すると、コンパイラが開き中かっこまたは関数呼び出しに遭遇したときに、現在のスタック ポインターで新しいスタック フレームをプッシュしてフレームをポップアウトするアセンブリ コードを生成するように見えるため、違いはないようです。閉じ中括弧または return ステートメントに遭遇すると、2 番目のケースの利点は、return ステートメントを使用して呼び出し元関数に値を返すことができることです。しかし、最初のケースではありません。

于 2015-06-14T16:46:23.917 に答える