이 가이드에서는 C에서 goto 문이 어떻게 작동하는지, 올바른 문법, 언제 유용할 수 있는지, 그리고 왜 현대 코드에서 일반적으로 권장되지 않는지 배웁니다.
goto 문 문법
goto label;
...
label: statement;
label은 콜론이 뒤따르는 식별자입니다. goto 문 실행 시 제어가 해당 레이블로 직접 점프합니다.
예제: goto로 루프 조기 탈출
#include <stdio.h>
int main() {
const int maxInput = 100;
int i;
double number, average, sum = 0.0;
for (i = 1; i <= maxInput; ++i) {
printf("%d. 숫자 입력: ", i);
scanf("%lf", &number);
/* 사용자가 음수 입력 시 루프 나머지 건너뛰기 */
if (number < 0.0) {
goto exit_loop;
}
sum += number;
}
exit_loop:
average = sum / (i - 1);
printf("Sum = %.2f\n", sum);
printf("Average = %.2f", average);
return 0;
}
출력
1. 숫자 입력: 3
2. 숫자 입력: 4.3
3. 숫자 입력: 9.3
4. 숫자 입력: -2.9
Sum = 16.60
Average = 5.53
대부분 개발자가 goto를 피하는 이유
goto 문은 읽기, 테스트, 유지보수가 어려운 "스파게티 코드"를 만들 수 있습니다. 예:
one:
for (i = 0; i < number; ++i) {
test += i;
goto two;
}
two:
if (test > 5) {
goto three;
}
// ...
중첩 범위를 벗어나거나 복잡한 제어 구조를 가로지르는 점프는 프로그램 흐름을 숨겨 진단하기 어려운 버그를 유발합니다.
goto가 여전히 적절한 경우
드물게 필요하지만 goto는 특정 시나리오를 단순화할 수 있습니다:
여러 플래그 없이 깊이 중첩된 루프에서 한 번에 탈출.
함수 종료 전 정리 코드 중앙화.
아주 제한적으로 사용하고, 미래 유지보수자가 점프 목적을 이해할 수 있게 의도를 문서화하세요.
goto를 사용해야 할까?
대부분 현대 C 프로그램에서 구조적 제어 흐름 구조(루프, 함수, switch 문)가 goto의 사용 케이스를 커버합니다. C 표준과 모범 사례 가이드라인은 타당한 이유가 없다면 피하라고 권장합니다. C++ 창시자 Bjarne Stroustrup은 "'goto'가 무엇이든 할 수 있다는 사실이 바로 우리가 사용하지 않는 이유다."라고 말했습니다.
결국 같은 로직을 명확하고 구조적인 코드로 구현할 수 있다면 그 길을 선택하세요. goto는 드물고 잘 정당화된 상황에만 예약하고 철저히 문서화하세요.