#include <iostream>
using namespace std;

void last() throw(int) // int 타입의 exception을 throw할 수도 있다 라는 뜻 // 불필요하다라는 견해도 있음
    					// 그냥 throw()라고 적으면 예외를 안던질거에요 하는 뜻 ... 이라도 적어줘야함
{
    cout << "last " << "\n";
    cout << "Throws exception" << "\n";
    
    throw -1;
    
    cout << "End last " << "\n";
}

void third()
{
    cout << "Third" << "\n";
    
    last();
    
    cout << "End third" << "\n";
}

void second()
{
    cout << "Second" << "\n";
    
    try
    {
        third();
    }
    catch(double)
    {
        cerr << "Second caught double exception" << "\n";
    }
    
    cout << "End second" << "\n";
}

void first()
{
    cout << "first" << "\n";
    
    try
    {
        second();
    }
    catch(int)
    {
        cerr << "first caught int exception" << "\n";
    }
    
    cout << "End first " << "\n";
}

int main()
{
	cout << "Start" << "\n";
	
	try
	{
		first();
	}
	catch(int) // first->second->third->last-> -1 만나고 first로 바로 옴. stack unwinding.
	{
		std::cerr << "main caught int exception" << "\n";
	}
    catch (...) // catch-all handlers
    {
        cerr << "main caught ellipses exception" << "\n";
    }
    
    cout << "End main" << "\n";
    
    return 0;
}

// Start
// first
// Second
// Third
// last
// Throws exception
// first caught in exception
// End first
// End main

// catch로 못잡거나 try가 없으면 stack unwinding.
// throw 'a'; 를 하면 에러를 잡지못해 RunTimeError 발생.