throw 절에 의해서 예외가 발생은 했는데, 이를 처리하지 않으면 어떻게 될까? 이번엔 이와 관련해서 이야기를 하고자 한다.

예외의 전달

MyFunc라는 함수를 호출했는데, 그 안에서 throw절이 실행되면서 예외가 발생했다. 그런데 이 함수내에는 예외처리를 위한 try~catch 문이 존재하지 않는다.

이러한 경우 예외처리에 대한 책임은 MyFunc를 호출한 영역으로 넘어가게 된다.

int main(void)
{
	int num1, num2;
	cout << ...
	cin >> ...
	
	try
	{
		Divide(num1, num2);
		cout << ...
	}
	catch(int expn)
	{
		cout << ..
		...
	}
	return 0;
}

예외상황이 발생한 위치와 예외상황을 처리해야 하는 위치가 다른 경우

int StoI(char *str)
{
	int len = strlen(str);
	int num = 0;
	if (예외)
	 throw expn;
}

int main()
{
try
	StoI(str);
catch
	...
}

“함수 내에서 함수를 호출한 영역으로 예외 데이터를 전달하면, 해당 함수는 더 이상 실행되지 않고 종료가 된다.”

스택 풀기(Stack Unwinding)

예외가 처리되지 않아서, 함수를 호출한 영역으로 예외 데이터가 전달되는 현상을 가리켜 ‘스택 풀기’라고 한다. 왜 이러한 이름이 붙게 되었는지 다음 예제를 통해서 이해해보자.

main → SImpleFuncOne → SimpleFuncTwo → SimpleFuncThree

호출된 함수의 역순으로 예외 데이터가 전달된다. 그리하여 결국 예외는 SimpleFuncThree 함수에서 발생했지만, 예외의 처리는 main 함수에서 이뤄지는 형태가 된다. 그런데 예외 데이터가 전달되면, 예외 데이터를 전달한 함수는 종료되기 때문에, 예외 데이터를 전달한 함수의 스택이 반환되는 것은 당연하다.

“예외가 처리되지 않아서, 예외 데이터가 main 함수에까지 도달했는데, main 함수에서조차 예외를 처리하지 않으면, terminate 함수 (프로그램을 종료시키는 함수)가 호출되면서 프로그램이 종료되어 버립니다.”

자료형이 일치하지 않아도 예외 데이터는 전달됩니다.

int SimpleFunc(void)
{
	try
	{
		if (...)
			throw -1;
	}
	catch (char expn)
	{
		...
	}
}

이 경우, 자료형의 불일치로 인해서 예외는 처리되지 않는다 (catch 블록으로 값이 전달되지 않는다.) 따라서 SimpleFunc 함수를 호출한 영역으로 예외 데이터가 전달된다.

하나의 try 블록과 다수의 catch 블록

try
{
}
catch (char ch)
{
}
catch (int expn)
{
}

가능하다.

전달되는 예외의 명시