7

私はC++の第6章の初期化とクリーンアップで考えを読んでいます。著者は言った:

実際には、コンパイラーは、スコープの最初の括弧でスコープにすべてのストレージを割り当てるというCの慣例に従う可能性が高くなります。プログラマーとして、ストレージが定義されるまでストレージにアクセスできないため、問題ではありません。ストレージはブロックの先頭に割り当てられますが、コンストラクターの呼び出しは、オブジェクトが定義されているシーケンスポイントまで発生しません。これは、それまで識別子が使用できないためです。コンパイラは、switchステートメントやgotoがジャンプできる場所など、シーケンスポイントが条件付きでのみ通過するオブジェクト定義を配置しないようにチェックします。

そして、作者は次のように例を示します。

class X {
public:
  X();
};

X::X() {}

void f(int i) {
  if(i < 10) {
   //! goto jump1; // Error: goto bypasses init
  }
  X x1;  // Constructor called here
 jump1:
  switch(i) {
    case 1 :
      X x2;  // Constructor called here
      break;
  // case 2 : // Error: case bypasses init
      X x3;  // Constructor called here
      break;
  }
} 

int main() {
  f(9);
  f(11);
}///:~

上記のコードが問題ない理由がわかりませんか?私の理解によると、そうでない場合はx2初期化をバイパスできます。i1

補足:

この文は、「コンパイラーは、スコープの最初の括弧でスコープにすべてのストレージを割り当てるというCの慣例に従う可能性が実際に高くなります。」また、私を混乱させました。

著者の説明によると、の冒頭の括弧で、コンパイラはすでにとswitchにスペースを割り当てています。この場合、初期化されない可能性があります(ケース1は満たされていません)。x2x3x2

4

4 に答える 4

5

私の理解によると、iが1でない場合、x2は初期化をバイパスできます。

いいえ、case 1実行されx2て定義され、ブロックの最後で破棄されるswitchか、ケースが実行されずブロック全体switchが何もしないためx2、スコープ内にないため、初期化されませんが、ブロックすることはできませんどちらかに言及。したがって、存在して安全に使用できるか、存在しないかのいずれかです。

于 2013-02-20T21:54:03.893 に答える
2

C++ オブジェクトの初期化と破棄のセマンティクスは、完全にジャンプ セーフです (例外、 goto 、 switch 、および loop コンストラクトが含まれます)。

(唯一の注目すべき例外は、C 標準ライブラリ (setjmp/longjmp) から継承されます)

6.6 ジャンプ文

2スコープから出ると (どのように達成されても)、そのスコープで構築された自動保存期間 (3.7.3) を持つオブジェクトは、それらの構築の逆の順序で破棄されます。[ 注: 一時的なものについては、12.2 を参照してください。—終わりの注]ループからの転送、ブロックからの転送、または自動ストレージ期間を持つ初期化された変数を過ぎた後の転送には、転送元のポイントではスコープ内にあるが転送先のポイントではスコープ内にない、自動ストレージ期間を持つオブジェクトの破棄が含まれます。 . (ブロックへの転送については 6.7 を参照)。[ 注: ただし、プログラムは、自動保存期間を持つクラス オブジェクトを破棄することなく (たとえば、std::exit() または std::abort() (18.5) を呼び出すことによって) 終了できます。—終わりのメモ]

于 2013-02-20T21:52:27.683 に答える
0

問題は、スコープを終了すると、ローカルで初期化された変数が破棄されることです。c ++は、変数の作成に関して、switch、if、while、forはすべて独自のスコープであると考えています。

于 2013-02-20T21:56:28.617 に答える
0

いいえ、 でx2あってもバイパスできませi1。の問題は、gotoそれが取られた場合、コンストラクターが呼び出されないことです(コンストラクターはステートメントx1で「呼び出される」ことを思い出してください-コンストラクターへの呼び出しはジャンプのターゲットのにあり、あなたはまだ範囲内にあったポイント。X x1;x1

しかし、その線を飛び越えて がスコープ内にあるポイントにたどり着くことはできないので、それで問題ありX x2;ません。x2

于 2013-02-20T21:58:43.467 に答える