2016-09-24 5 views
2

コードで遊んでいるときに面白い特殊性が発生しました。私はCygwinとC++ 14でEclipse CDT 4.5.2を使用しています(-std = C++ 14)。 CASEの内部変数の初期化は、通常は禁止さが、次のコードがコンパイルされます。SWITCHステートメントのDEFAULTの後のCASE内でのC++変数の初期化

switch(int switchStatement = 11) 
{ 
    default: 
     ++j; 
     break; // break is optional, still compiles even if omitted 
    case 11: 
     int caseVariable = 0; 
     ++j; 
} 

別のケースが追加された場合は、例外「ジャンプの場合にラベルが」発生します。

switch(int switchStatement = 11) 
{ 
    default: 
     ++j; 
    case 11: 
     int caseVariable = 0; 
     ++j; 
    case 12: // exception 
     ++j; 
} 

誰かがどのようにすべての作品を説明することができますか?

+0

Reopened:dupeはスニペットの1つのコンパイルの成功を説明しませんでした。 (私はそれがコンパイラのバグだと思う) – Bathsheba

+0

ケース11にブレークを追加すると機能しませんか? –

+0

変数宣言が最後の 'case'ブロックにある場合にのみ機能しますか? –

答えて

1

なぜ2番目のケースでエラーが発生しますが、最後のcaseステートメントで変数を宣言するとエラーが発生しないのですか?

ジャンプが変数 の宣言を同じスコープ内で渡すことができないのはC++のルールです。したがってケース2にジャンプすると、ケース1では変数の宣言 を渡します。しかし、 の最後のケースの変数の宣言は決してジャンプしないため、OKです。

変数のジャンプを許可した場合、 宣言では、コンパイラが にその変数のデストラクタを呼び出すかどうかを決定するのは非常に難しいでしょう。 変数宣言を飛び越した場合は、デストラクタを呼び出す必要はありません。 にジャンプしていないとしたら、あなたはそうするでしょう。

1つのcase文で宣言され、初期化された変数は、他のcaseブロックでも表示されますが、初期化コードが別のケースに属するため初期化されません。

C++の問題はスコープの問題です。ここで、case文は「ラベル」です。したがって、コンパイラは1つのステートメントから別のステートメントへジャンプするためにそれらを扱います。この特定の例では、コンパイラはさらに進める方法を理解しません。この問題を解決するには、ケース内のコードを{}ブロックに含めることができます。余分な{と}は、コンパイラがデストラクタを呼び出すときに問題なく動作することを意味します。したがって、新しい変数を宣言している間に、その特定のcase文にスコープまたは中括弧を指定することが重要です。

+0

あなたはなぜあなたの答えを2回投稿しましたか?いつでも編集できます。 –

+0

誤ってそれが私が2番目の投稿を削除した理由です –

関連する問題