Stack Unwinding(스택 되감기)

일반적으로 어떤 함수 호출 시 이 함수를 호출한 함수의 대한 주소를 call stack에 저장하고, 함수가 종료되면 stack에서 address를 pop하여 호출한 함수를 다시 호출한다. 이 일반적인 과정에서 Stack Unwinding(스택 되감기)는 pop과정에서 발생하게 되고, 함수 block안에 try~catch문에서 함수의 호출을 하다가 호출한 함수 내부에 어떠한 예외가 발생하였을 때 stack에 저장되었던 function의 address들이 제거되어 최초 try~catch를 호출한 fuction으로의 호출이 되는 것을 말한다.

#include <iostream>
using namespace std;

void function1() throw (int) { //this function throws exception
   cout<<"\n Entering into function 1";
   throw 100;
   cout<<"\n Exiting function 1";
}

void function2() throw (int) { //This function calls function 1
   cout<<"\n Entering into function 2";
   function1();
   cout<<"\n Exiting function 2";
}

void function3() { //function to call function2, and handle
   //exception thrown by function1
   cout<<"\n Entering function 3 ";
   try {
      function2(); //try to execute function 2
   }
   catch(int i) {
      cout<<"\n Caught Exception: "<<i;
   }
   cout<<"\n Exiting function 3";
}

int main() {
   function3();
   return 0;
}
Entering function 3
Entering into function 2
Entering into function 1
Caught Exception: 100
Exiting function 3

위 코드 처럼 function3->function2->function1로의 호출이 exception을 만나 최초 exception 블록을 설정한 function을 찾으러 가게되고 결국 function3의 exception을 catch하는 문을 찾으러 function1과 function2의 블록을 자동으로 스택 반환된다. 이를 stack unwinding이라 한다. 즉 함수내에서 함수를 호출한 영역으로 예외데이터를 전달하면, 함수는 더이상 실행되지 않고 곧바로 종료가 된다.

 

(1) throw한 예외 데이터의 자료형이 catch에서 받는 자료형과 일치하지 않는 경우

try block에서 exception이 발생되었지만, catch구문에서 자료형이 불일치한 경우 예외 데이터가 외부로 넘겨지게 되고 외부에서도 처리를 못하면 error가 발생하게 된다.

#pragma once
#include <iostream>
using namespace std;

void function1() throw (int) { //this function throws exception
    cout << "\n Entering into function 1";
    throw 100;
    cout << "\n Exiting function 1";
}

void function2() throw (int) { //This function calls function 1
    cout << "\n Entering into function 2";
    function1();
    cout << "\n Exiting function 2";
}

void function3() { //function to call function2, and handle
    //exception thrown by function1
        cout << "\n Entering function 3 ";
    try {
        function2(); //try to execute function 2
    }
    catch (double i) {
        cout << "\n Caught Exception: " << i;
    }
    cout << "\n Exiting function 3";
}

void execute() {
    try {
        function3();
    }
    catch (int i) {
        cout << "\n Caught Exception: " << i;
    }
}

int main()
{
    execute();
}

위 function3에서 int에 대한 exception을 처리 못하게 되면 execute 함수에서 예외를 처리하게 된다.

 

(2) 명시적인 throw

함수에서 일어나는 exception 유형을 명시적으로 하고자 할때는 함수명 옆에 throw(type1, type2)을 넣어주면 된다. 만약 다른 자료형의 예외가 발생하게 되면 terminate함수로 인해 프로그램이 종료된다.

void function3() throw(double) { //function to call function2, and handle
    //exception thrown by function1
        cout << "\n Entering function 3 ";
    try {
        function2(); //try to execute function 2
    }
    catch (double i) {
        cout << "\n Caught Exception: " << i;
    }
    cout << "\n Exiting function 3";
}

'프로그래밍 > C & C++' 카테고리의 다른 글

Smart Pointer  (0) 2020.04.22
Virtual Function  (0) 2020.04.21
Dangling Pointer(허상 포인터)  (0) 2020.04.17
Vector 컨테이너  (0) 2020.04.09
STL Vector와 List의 차이점  (0) 2020.03.25
더보기

댓글,

야미야미얌얌

프로그래밍 및 IT 기술