Quick Flow
switch는 enum처럼 하나의 이산 값을 여러 case로 나눌 때 씁니다. 범위 비교는 if가 더 직접적이며, case 안에서 선언한 변수는 block으로 감싸 다음 label을 건너뛰지 않게 합니다.
#include <iostream>
enum class Mode { off, warmup, run };
int main() {
Mode mode = Mode::warmup;
switch (mode) {
case Mode::off:
std::cout << "off\n";
break;
case Mode::warmup: {
int level = 1;
std::cout << level << "\n";
[[fallthrough]]; // C++17: 다음 case로 의도적으로 계속 실행
}
case Mode::run:
std::cout << "running\n";
break;
}
}[[fallthrough]]는 실행되는 case의 끝과 다음 label 사이에 둡니다. jump table은 compiler가 선택할 수 있는 구현 방식일 뿐, switch를 if보다 빠르게 보장하지는 않습니다.
문법
switch 선택과 점프 테이블
switch는 정수·enum처럼 이산 값 하나를 여러 상수 case와 비교할 때 읽기 좋습니다. 컴파일러는 값의 분포와 각 분기의 코드에 따라 점프 테이블, 비교 트리, 다른 방식을 선택할 수 있으므로 switch가 if보다 빠르다고 보장하지 않습니다.
int result = 0;
switch (command) {
case 0: result = 10; break;
case 1: result = 20; break;
default: result = -1; break;
}fallthrough — 의도와 실수 구분
break가 없으면 다음 case로 흐릅니다(fallthrough). 실수인 경우가 많지만 의도적으로 쓸 때도 있습니다. C++17의 [[fallthrough]] 속성으로 의도를 명시하면 컴파일러 경고를 억제하고 독자에게도 표시됩니다.
// 의도적 fallthrough — 여러 case에 같은 동작
switch (c) {
case 'a': case 'e': case 'i': case 'o': case 'u':
std::cout << "vowel\n";
break;
case ' ': case '\t': case '\n':
[[fallthrough]]; // C++17: 다음 case로 의도적 이동
default:
std::cout << "other\n";
break;
}case 안의 지역 변수 — 반드시 {} 로 묶기
switch 전체는 하나의 스코프입니다. case 안에서 변수를 선언하고 {}로 묶지 않으면 다른 case에서 그 선언을 건너뛰는 점프가 생겨 컴파일 오류가 납니다.
switch (x) {
case 1:
int n = 10; // ❌ 컴파일 오류 가능 — 다른 case가 선언을 건너뜀
break;
case 2:
std::cout << n; // n이 초기화됐는지 알 수 없음
break;
}
// ✅ {}로 스코프 분리
switch (x) {
case 1: {
int n = 10;
std::cout << n;
break;
}
case 2: {
int n = 20; // 별도 스코프, 충돌 없음
std::cout << n;
break;
}
}enum class + switch — 누락 case 감지
enum class와 switch를 함께 쓰면 컴파일러가 처리되지 않은 열거값에 대해 경고를 줍니다.
enum class Dir { North, South, East, West };
std::string name(Dir d) {
switch (d) {
case Dir::North: return "N";
case Dir::South: return "S";
case Dir::East: return "E";
// ❌ West 누락 — 컴파일러 경고 (-Wswitch)
}
return "?";
}체크포인트
| 상황 | 적합한 선택 |
|---|---|
| 이산 정수/enum 값 분기 | switch (가독성과 case 누락 검토) |
| 범위 비교, 복합 조건 | if-else if |
| 의도적 fallthrough | [[fallthrough]] (C++17) |
| case 안 지역 변수 | case X: { ... break; } |
| 누락 case 감지 | enum class + -Wswitch |
주의할 점
break를 빠뜨리면 다음 case로 정의된 fallthrough가 발생합니다. 의도가 아니라면 버그가 되므로 [[fallthrough]]로 구분합니다.
switch (grade) {
case 'A':
bonus = 100;
// ❌ break 누락 — B 케이스까지 실행됨
case 'B':
bonus = 50;
break;
}
// grade == 'A'여도 bonus = 50이 됨
// ✅ 각 case에 break 명시
switch (grade) {
case 'A': bonus = 100; break;
case 'B': bonus = 50; break;
default: bonus = 0; break;
}참고 링크
1 sources