0. 스택 되감기의 발생

C++ 예외처리에서 예외를 던지는 throw는 try구문 안에 있어야 하며, throw 발생 시 예외를 받아주는 catch구문으로 점프하게 됩니다.

함수 내에서 try, catch 구문이 없고 throw만 발생시키는 함수도 있는데, 이 경우 catch를 찾기 위해 함수 외부를 찾게 됩니다.


예외를 던진 함수의 외부에서 catch를 찾기 위해 현재의 스택정보를 정리하고 빠져나가는 스택 되감기(Stack Unwinding)가 발생합니다.

아래 예제는 스택 되감기의 예제입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
void f1();  // f2를 호출합니다.
void f2();  // f3를 호출합니다.
void f3();  // 예외를 던집니다.
 
void main()
{
    cout << "enter: main" << endl;
    
    f1();
    
    cout << "exit: main" << endl;
}
 
void f1()
{
    cout << "enter: f1" << endl;    
    
    try{ 
        f2();
    }catch(int value){
        cout << "catch: f1" << endl;
    }
    
    cout << "exit: f1" << endl;    
}
 
 
void f2()
{
    cout << "enter: f2" << endl;    
    
    try{ 
        f3();
    }catch(double value){
        cout << "catch: f2, value: " << value << endl;
    }
    
    cout << "exit: f2" << endl;    
}
 
void f3()
{
    cout << "enter: f3" << endl;
    
    throw 10;
    
    cout << "exit: f3" << endl;
}
cs


결과:


enter: main
enter: f1
enter: f2
enter: f3
catch: f1
exit: f1
exit: main


예외를 던지며 catch가 없는 f3, double형 예외를 받는 f2는 함수 진입은 했지만, 함수의 끝에 도달하지 못했습니다.

또한, 예외를 받은 f1은 catch구문 이후에 정상적으로 프로그램이 작동하였음을 알 수 있습니다.


그렇다면, 스택 되감기는 왜 발생하는지를 알아보겠습니다.




1. 발생 이유

우선, 스택 되감기가 발생하는 이유를 알기 위해선 스택 프레임에 대해 알고 있어야 합니다.

함수가 호출될 때 스택에는 매개변수로 전달되는 인자 값, 함수의 반환 값, 함수를 마치고 복귀할 번지수, 지역변수 등의 정보가 저장되는데, 이러한 정보를 스택프레임 이라고 합니다.


임시적인 정보를 저장하기 위해 스택을 사용하되, 푸시 회수와 팝 회수가 일치하므로 함수를 호출하고 나면 호출 전의 상태와 같습니다.

이처럼 함수는 호출자(caller)와 피호출자(callee)가 서로 협조하여 스택의 항상성을 유지합니다.


본론으로 돌아와서, 스택 되감기의 이유는 스택의 항상성 유지에 있습니다. 

함수 내에서 예외가 발생하였을 때 외부의 catch구문으로 바로 점프한다면 스택 프레임의 항상성을 유지할 수 없게 됩니다. 

때문에 예외 발생시, 함수 내부에 catch 구문이 없다면 스택프레임의 항상성 유지를 위해 호출원을 거슬러 올라가여 스택을 정리하며 빠져나가게 됩니다.


참고: 혼자 연구하는 C/C++ (http://soen.kr/lecture/ccpp/cpp3/32-1-3.htm), 

       스택 프레임 (http://tadis.tistory.com/entry/%ED%98%B8%EC%B6%9C%EA%B7%9C%EC%95%BD)

'C++ > C++ 일반' 카테고리의 다른 글

선언과 정의(declaration and definition)  (2) 2018.10.22
인라인(inline) 함수  (0) 2018.10.12
원자성(atomicity)  (0) 2018.10.11
불변속성(invariant)  (0) 2018.10.10
예외 안전성 보장(exception-safety guarantee)  (0) 2018.09.21

+ Recent posts