switch文でbreakを忘れて後続のcaseまで実行されるバグ
switch文の各case節末尾にbreakを書き忘れ、該当したcase以降のすべての節が続けて実行されてしまうバグです。
なぜエラーが出ないのか
出力: Mon\nTue
(エラーなし)- C++は何も報告しません。コンパイルも実行も正常に完了するためです
出力: Mon\nTue- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 #include <iostream> 2 int main() { 3 int day = 1; 4 switch (day) { 5 case 1: 6 std::cout << "Mon" << std::endl; 7 ^ 8 case 2: 9 std::cout << "Tue" << std::endl; 10 break; 11 case 3: 12 std::cout << "Wed" << std::endl; 13 break; 14 } 15 return 0; 16 }
出力: Mon\nTue期待: Mon のみ
case 1の末尾にbreakが無いため、一致したcase 1の処理が終わったあとも止まらずcase 2まで続けて実行されてしまいます。
直し方: (空) を break; にします。
広告
広告スロット(未設定)
パターン2
1 #include <iostream> 2 int main() { 3 int level = 1; 4 switch (level) { 5 case 1: 6 std::cout << "low" << std::endl; 7 ^ 8 case 2: 9 std::cout << "mid" << std::endl; 10 break; 11 case 3: 12 std::cout << "high" << std::endl; 13 break; 14 } 15 return 0; 16 }
出力: low\nmid期待: low のみ
case 1の末尾にbreakが無いため、一致したcase 1の処理が終わったあとも止まらずcase 2まで続けて実行されてしまいます。
直し方: (空) を break; にします。
パターン3
1 #include <iostream> 2 int main() { 3 int grade = 1; 4 switch (grade) { 5 case 1: 6 std::cout << "A" << std::endl; 7 ^ 8 case 2: 9 std::cout << "B" << std::endl; 10 break; 11 case 3: 12 std::cout << "C" << std::endl; 13 break; 14 } 15 return 0; 16 }
出力: A\nB期待: A のみ
switchはbreakに出会うかブロックの終わりに達するまで、上から下へすべての文を実行し続けます(フォールスルー)。
直し方: (空) を break; にします。
よくある誤解
「一致したcaseの中身だけが実行される」というのは誤解です。C++のswitchはbreakに出会うかswitchブロックの終わりに達するまで、上から下へすべての文を実行し続けます(フォールスルー)。
まとめ
switch文でbreakを忘れて後続のcaseまで実行されるバグは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。