私は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
初期化をバイパスできます。i
1
補足:
この文は、「コンパイラーは、スコープの最初の括弧でスコープにすべてのストレージを割り当てるというCの慣例に従う可能性が実際に高くなります。」また、私を混乱させました。
著者の説明によると、の冒頭の括弧で、コンパイラはすでにとswitch
にスペースを割り当てています。この場合、初期化されない可能性があります(ケース1は満たされていません)。x2
x3
x2