17.4. Stack Unwinding

When an exception is thrown but not caught in a particular scope, the function call stack is “unwound,” and an attempt is made to catch the exception in the next outer try...catch block. Unwinding the function call stack means that the function in which the exception was not caught terminates, all local variables that have completed intitialization in that function are destroyed and control returns to the statement that originally invoked that function. If a try block encloses that statement, an attempt is made to catch the exception. If a try block does not enclose that statement, stack unwinding occurs again. If no catch handler ever catches this exception, the program terminates. The program of Fig. 17.4 demonstrates stack unwinding.


 1   // Fig. 17.4: fig17_04.cpp
 2   // Demonstrating stack unwinding.
 3   #include <iostream>
 4   #include <stdexcept>
 5   using namespace std;
 6
 7   // function3 throws runtime error
 8   void function3()
 9   {
10      cout << "In function 3" << endl;
11
12      // no try block, stack unwinding occurs, return control to function2
13      throw runtime_error( "runtime_error in function3" ); // no print
14   } // end function3
15
16   // function2 invokes function3
17   void function2()
18   {
19      cout << "function3 is called inside function2" << endl;
20      function3(); // stack unwinding occurs, return control to function1
21   } // end function2
22
23   // function1 invokes function2
24   void function1()
25   {
26      cout << "function2 is called inside function1" << endl;
27      function2(); // stack unwinding occurs, return control to main
28   } // end function1
29
30   // demonstrate stack unwinding
31   int main()
32   {
33      // invoke function1
34      try
35      {
36         cout << "function1 is called inside main" << endl;
37         function1(); // call function1 which throws runtime_error
38      } // end try
39      catch ( runtime_error &error ) // handle runtime error
40      {
41         cout << "Exception occurred: " << error.what() << endl;
42         cout << "Exception handled in main" << endl;
43      } // end catch
44   } // end main


function1 is called inside main
function2 is called inside function1
function3 is called inside function2
In function 3
Exception occurred: runtime_error in function3
Exception handled in main


Fig. 17.4. Stack unwinding.

In main, the try block (lines 34–38) calls function1 (lines 24–28). Next, function1 calls function2 (lines 17–21), which in turn calls function3 (lines 8–14). Line 13 of function3 throws a runtime_error object. However, because no try block encloses the throw statement in line 13, stack unwinding occurs—function3 terminates at line 13, then returns control to the statement in function2 that invoked function3 (i.e., line 20). Because no try block encloses line 20, stack unwinding occurs again—function2 terminates at line 20 and returns control to the statement in function1 that invoked function2 (i.e., line 27). Because no try block encloses line 27, stack unwinding occurs one more time—function1 terminates at line 27 and returns control to the statement in main that invoked function1 (i.e., line 37). The try block of lines 34–38 encloses this statement, so the first matching catch handler located after this try block (line 39–43) catches and processes the exception. Line 41 uses function what to display the exception message.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.105.255