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


8

これを仮定します:

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

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


1
これは実装が定義されているため、さまざまなコンパイラーによって生成されたコードの例をいくつか見て、考えを理解する必要があります。このMicrosoftによる講演では、プレゼンターがVisualC ++コンパイラで「スタックパッキング」と呼んでいるものについて簡単に説明しています。
2015

回答:


12

コンパイラがスペースを予約するだろうと誰が言ったのか(登録のみ可能)

これは完全に未定義です。
あなたが言うことができるすべてはそれ(x)は内部ブロック内からのみアクセスできるです。

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

funcに入るとすぐにxのスペースがスタックに予約されます

未定。

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

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

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

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

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

はい


3
私が心配することを断定うあまりにも多くのコンパイラは、これはほとんどのアプリケーションに時期尚早な最適化だろうどのように処理するかについて。
TehShrike、2011

4

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

  • コンパイラがないではない離れて最適化する任意のローカル変数を。(おそらく、明示的にとして定義されている変数を除きますregisterが、それは検証されます。)

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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.