ちょっとしたタイプミスで、偶然この構造を見つけました:
int main(void) {
char foo = 'c';
switch(foo)
{
printf("Cant Touch This\n"); // This line is Unreachable
case 'a': printf("A\n"); break;
case 'b': printf("B\n"); break;
case 'c': printf("C\n"); break;
case 'd': printf("D\n"); break;
}
return 0;
}
printf
ステートメントの先頭にあるは有効であるようですswitch
が、完全に到達不可能でもあります。
到達不能なコードに関する警告さえ出ずに、クリーンなコンパイルができましたが、これは無意味に思えます。
コンパイラはこれを到達不能コードとしてフラグ付けする必要がありますか?
これは何か目的がありますか?
ベストアンサー1
最も役に立つものではないかもしれないが、完全にswitch
価値はありません。スコープ内で使用可能なローカル変数を宣言するために使用できます。
switch (foo)
{
int i;
case 0:
i = 0;
//....
case 1:
i = 1;
//....
}
標準(N1579 6.8.4.2/7
)には次のサンプルがあります。
例 人工プログラムフラグメント
switch (expr) { int i = 4; f(i); case 0: i = 17; /* falls through into default code */ default: printf("%d\n", i); }
識別子が であるオブジェクトは、
i
自動記憶域期間 (ブロック内) で存在しますが、初期化されることはなく、したがって、制御式の値が 0 以外の場合、printf
関数の呼び出しは不確定な値にアクセスします。同様に、関数の呼び出しにはf
到達できません。
追伸ちなみに、サンプルは有効な C++ コードではありません。その場合 ( N4140 6.7/3
、強調は筆者による):
自動保存期間を持つ変数がスコープ外にあるポイントからスコープ内にあるポイントまで90 度ジャンプするプログラムは不正な形式です。変数がスカラー型でない限り、単純なデフォルトコンストラクタと単純なデストラクタを持つクラス型、これらの型のいずれかの cv 修飾バージョン、または前述の型のいずれかの配列初期化子なしで宣言されている(8.5)。
90) 文の条件から
switch
ケースラベルへの移行は、この点ではジャンプと見なされます。
したがって、 をint i = 4;
に置き換えると、int i;
有効な C++ になります。