익명 사용자
로그인하지 않음
계정 만들기
로그인
youngwiki
검색
Nonlocal Jump 문서 원본 보기
youngwiki
이름공간
문서
토론
더 보기
더 보기
문서 행위
읽기
원본 보기
역사
←
Nonlocal Jump
문서 편집 권한이 없습니다. 다음 이유를 확인해주세요:
요청한 명령은 다음 권한을 가진 사용자에게 제한됩니다:
사용자
.
문서의 원본을 보거나 복사할 수 있습니다.
상위 문서: [[Exceptional Control Flow]] ==개요== '''Nonlocal jump'''는 사용자 수준의 exceptional control flow을 제공한다. 이는 '''정상적인 호출이나 반환 순서를 거치지 않고 현재 실행 중인 한 함수에서 다른 함수로 직접 control을 전이'''시키는 역할을 한다. ==Nolocal functions== Nonlocal jump는 <code>setjmp()</code>, <code>longjmp()</code> 함수들에 의해 구현된다. <syntaxhighlight lang="cpp"> #include <setjmp.h> //Returns: 0 from setjmp, nonzero from longjmps int setjmp(jmp_buf env); //세이브 포인트 찍기 int sigsetjmp(sigjmp_buf env, int savesigs); </syntaxhighlight> <code>setjmp()</code> 함수는 현재의 호출 환경(calling environment)를 env 버퍼에 저장하여 <code>longjmp()</code> 함수에서 사용하도록 한 후, 0을 반환한다. 이때 호출 환경은 프로그램 카운터, 스택 포인터, 범용 레지스터(general-purpose registers)들을 포함한다. 이때, <code>setjmp()</code>의 반환값을 변수에 할당해서는 안된다. <syntaxhighlight lang="cpp"> #include <setjmp.h> //never returns void longjmp(jmp_buf env, int retval); //문제가 생겼으니 세이브 포인트로 후퇴 void siglongjmp(sigjmp_buf env, int retval); </syntaxhighlight> <code>longjmp()</code> 함수는 env 버퍼로부터 호출 환경을 복원한 다음 해당 env를 초기화한 다음, 해당 env를 초기화한 최신의 <code>setjmp()</code> 함수의 return을 야기한다. 이때 <code>setjmp()</code> 함수는 0이 아닌 retval 값을 return하며 복귀한다.<br> 즉, <code>setjmp()</code> 함수는 한 번 호출되지만 여러 번 반환된다. 한 번은 <code>setjmp()</code> 함수가 처음 호출되어 호출 환경이 env 버퍼에 저장될 때이고, 나머지는 각각의 <code>longjmp()</code> 함수 호출에 대응하여 반환될 때이다. 반면, <code>longjmp()</code> 함수는 한 번 호출되지만 절대 반환되지 않는다. 비유를 하자면, <code>setjmp()</code>, <code>longjmp()</code> 함수들은 닥터 스트레인지의 마법과 비슷하다. <code>setjmp()</code>는 닥터 스트레인지가 도르마무와 맞서기 위해서 스폰 포인트를 찍어두는 곳이고, <code>longjmp()</code>는 닥터 스트레인지가 도르마무에게 죽는 곳이다. 즉, 닥터 스트레인지가 도르마무에게 죽으면 특정한 시간대로 돌아 가듯이, 코드가 <code>longjmp()</code>에 이르면 control이 강제로 <code>setjmp()</code> 지점으로 이동되며, 이를 통해서 <code>setjmp()</code>는 두 번 반환될 수 있다. Nonlocal jump의 중요한 용도 중 하나는, 깊이 중첩된 함수 호출 내부에서 어떤 오류 조건이 감지되었을 때 즉시 return하도록 하는 것이다. 중첩된 함수 호출 내부 깊은 곳에서 오류 조건이 발생한 경우, 호출 스택(call stack)을 힘겹게 하나하나 풀어내는 대신, nonlocal jump를 이용해 common localized error handler로 직접 return할 수 있다.<br> Nonlocal jump의 또 다른 중요한 용도는, 시그널 핸들러(signal handler)로부터 인터럽트(interruted)된 명령어로 복귀하는 대신, 특정 코드 위치로 분기(branch out)하는 것이다. ==Nonlocal examples== ===Nonlocal example 1=== <syntaxhighlight lang="cpp"> #include "csapp.h" jmp_buf buf; int error1 = 0; int error2 = 1; void foo(void), bar(void); int main() { switch(setjmp(buf)) { case 0: foo(); break; case 1: printf("Detected an error1 condition in foo\n"); break; case 2: printf("Detected an error2 condition in foo\n"); break; default: printf("Unknown error condition in foo\n"); } exit(0); } /* Deeply nested function foo */ void foo(void) { if (error1) longjmp(buf, 1); bar(); } void bar(void) { if (error2) longjmp(buf, 2); } </syntaxhighlight> ===Nonlocal example 2=== <syntaxhighlight lang="cpp"> </syntaxhighlight> <syntaxhighlight lang="cpp"> </syntaxhighlight> ==각주== [[분류:컴퓨터 시스템]]
Nonlocal Jump
문서로 돌아갑니다.
둘러보기
둘러보기
대문
최근 바뀜
임의의 문서로
미디어위키 도움말
위키 도구
위키 도구
특수 문서 목록
문서 도구
문서 도구
사용자 문서 도구
더 보기
여기를 가리키는 문서
가리키는 글의 최근 바뀜
문서 정보
문서 기록