web-dev-qa-db-ja.com

c / c ++では、ブロックが実行される場合にのみブロックスコープ変数がスタックされますか?

これを仮定します:

void func()
{
 ...
 if( blah )
 {
  int x;
 }
 ...
}  

xが入力された直後、またはブロックが実際に実行された場合のみ、funcのスペースがスタックに予約されますか?
それともコンパイラの選択ですか?
CとC++はこれについて同じように動作しますか?

8
Petruza

コンパイラがスペースを予約するだろうと述べた人(登録のみ可能)。

これは完全に未定義です。
言えることは、それ(x)は内部ブロック内からのみアクセスできるということです。

コンパイラがメモリを割り当てる方法(存在する場合でもスタック上)は完全にコンパイラ次第です(メモリ領域が複数のオブジェクトで再利用される可能性があるため(コンパイラがそれらの寿命が重複しないことを証明できる場合))。

Funcに入るとすぐにスタックに予約されるxのスペースです。

未定。

またはブロックが実際に実行された場合のみ?

未定。
ただし、xがクラスオブジェクトの場合、ブロックが入力された場合にのみコンストラクタが実行されます。

それともコンパイラの選択ですか?

コンパイラーはメモリーを割り振らないこともあります。

CとC++はこれについて同じように動作しますか?

はい

12
Martin York

まあ、それは本当にコンパイラの選択ですが、私が観察したのは、私が最適化なしでコンパイル(これは通常、コードをデバッグできるようにするために行うことです)かなり明確で、確定的で、信頼できる方法で物事を行うには:

  • コンパイラーは、ローカル変数をしない最適化anyしません。 (おそらく、明示的にregisterとして定義されている変数を除きますが、それは確認する必要があります。)

  • すべてのローカル変数のスタックスペースは、それらがどのようにネストされていても、関数に入るときにすぐに予約されます。

  • スタックスペースは、ネストされた個別のスコープ間で再利用されません。これは、void f(){ { int x; } { int y; } }が2つのint変数にスペースを割り当てることを意味します。 xに割り当てられたスペースはyに再利用されません。

もちろん、最適化を有効にすると、Loki Astariが承認された回答に書き込んだことがすべて当てはまります。

4
Mike Nakis