개요
setjmp()와 longjmp()는 C언어의 goto문과 유사하지만 다소 차이가 있다. goto문 같은 경우는 실행중의 EIP(또는 Program Count)만 변경되지만, setjmp()/longjmp()는 프로그램의 스택도 변경시킨다. Goto문 같은 경우는 local jump를 지원하지만, setjmp는 nonlocal 점프도 할 수 있다. 즉 Goto문은 같은 함수내에서만 점프할 수 있지만, setjmp는 저장된 jmp_buf로 향하여 점프하기 때문에, 같은 함수내에서 있을 필요가 없다. 중요한 사실은 점프문은 매우 위험하고 피해야할 프로그래밍 스킬이라는 것이다.
- #include <setjmp.h> 헤더를 통해서 include한다.
- int setjmp(jmp_buf env) 직접 호출하면 0을 리턴하고 longjmp를 통해서 리턴하면 0이 아닌 값을 리턴하게 된다.
- void longjmp(jmp_buf env, int val)을 통해서 longjmp 구문에 들어가게 된다. val은 setjmp 호출에 대해 반환되는 값이다.
주의해야 하는 것은 setjmp를 한 함수가 return되었을 경우 longjmp를 수행하면 현재 stack frame그대로 setjmp를 함수의 stackframe처럼 반영하여 함수를 실행하게 되기 때문에, 예측 할 수 없는 결과를 가져올 수 있다는 것이다. 따라서 setjmp와 longjmp는 주의깊게 사용되어져야 한다. 즉 setjmp를 한 함수가 return되면 그 setjmp를 한 함수로 longjmp를 수행해서는 안됀다.
예제
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <signal.h>
void p1();
void intHandler();
jmp_buf env;
int main()
{
signal( SIGINT, intHandler );
if( setjmp( env ) != 0 ){
printf( "오류로 인해 복귀\n" );
exit( 0 );
}
else
printf( "처음 통과\n" );
p1();
}
void p1()
{
while( 1 ){
printf( "루프\n" );
sleep( 1 );
}
}
void intHandler()
{
printf( "인터럽트\n" );
longjmp( env, 1 );
}