C의 setjmp()와 longjmp()란?
이번 글에서는 C 언어의 setjmp()와 longjmp() 함수에 대해 자세히 알아보겠습니다. 두 함수는 비지역 점프(non-local jump)를 수행하는 저수준 제어 흐름 도구로, 모두 setjmp.h 헤더 파일에 정의되어 있습니다. 기본 문법은 다음과 같습니다.
setjmp(jmp_buf buf) : 현재 실행 위치를 buf에 저장하고, 처음 호출 시 0을 반환한다.
longjmp(jmp_buf buf, i) : buf가 가리키는 위치로 되돌아가며, 해당 지점에서 i를 반환값으로 전달한다.
C 언어에는 try-catch와 같은 예외 처리 구문이 내장되어 있지 않기 때문에, 이 두 함수를 조합하면 간단한 예외 처리 메커니즘을 구현할 수 있습니다. 즉, setjmp()를 try 블록처럼, longjmp()를 throw 문처럼 활용하는 것입니다. longjmp()가 호출되면 프로그램의 제어 흐름이 setjmp()가 미리 저장해 둔 지점으로 즉시 되돌아갑니다.
그럼 실전 예제로, 재귀 호출도, 반복문도, 매크로 확장도 사용하지 않고 숫자 5를 100번 출력하는 프로그램을 setjmp()와 longjmp()만으로 작성해 보겠습니다.
예제 코드
#include <stdio.h>
#include <setjmp.h>
jmp_buf buf;
main() {
int x = 1;
setjmp(buf); // buf를 사용해 점프 위치 설정
printf("5"); // 숫자 출력
x++;
if (x <= 100)
longjmp(buf, 1); // setjmp가 저장한 위치로 점프
}
실행 결과
5555555555555555555555555555555555555555555555555555555555555555555555555555
555555555555555555555555
동작 원리
코드의 실행 흐름을 단계별로 살펴보면 다음과 같습니다.
1. setjmp(buf)가 처음 호출되면 현재 실행 지점(스택 컨텍스트)이 buf에 저장되고 0을 반환합니다.
2. printf("5")로 숫자 5를 출력한 뒤 변수 x를 1 증가시킵니다.
3. x가 아직 100 이하라면 longjmp(buf, 1)이 호출되어, setjmp()가 저장해 둔 지점으로 제어가 되돌아갑니다.
4. 이후 다시 printf부터 if 검사까지의 과정이 반복되며, x가 100을 초과하는 순간 조건이 거짓이 되어 프로그램이 종료됩니다.
결국 setjmp()와 longjmp()의 반복적인 점프가 마치 루프처럼 작동하여, 어떠한 반복문이나 재귀 없이도 총 100개의 숫자를 화면에 출력하게 됩니다.
주의 사항
setjmp/longjmp는 강력한 기능이지만 남용하면 코드의 가독성과 유지 보수성이 크게 떨어질 수 있습니다. 또한 C++ 환경에서는 객체의 소멸자가 정상적으로 호출되지 않는 등의 문제가 발생할 수 있으므로, 임베디드 시스템이나 에러 복구 로직처럼 특수한 상황에서만 신중하게 사용하는 것이 바람직합니다.