Structured Exception Handling: try, catch, throw & Stack Unwinding
Idea in plain words
try block: Encloses code that may trigger runtime errors; throw: Signals that an exceptional error occurred; catch block: Handles the exception.
Explanation
Structured exception handling cleanly decouples error detection from error resolution. By bubbling errors up the call stack, functions encountering failures do not need to rely on awkward error return codes or global flags.
Key points
- Catch-all Handler (catch(...)): Catches any exception type not caught by preceding catch blocks.
- Stack Unwinding: The runtime automatically destroys all local stack objects created inside the try block before entering the catch handler.
- Re-throwing Exceptions: A catch handler can re-throw the caught exception upward using throw; without arguments.
Example
Example
Custom exception class: class InsufficientFundsException : public exception { public: const char* what() const noexcept override { return 'Balance too low'; } };
Code examples
// Exception Handling Demonstration in C++
#include <iostream>
#include <stdexcept>
using namespace std;
double divide(double a, double b) {
if (b == 0) {
throw invalid_argument("Division by zero error!"); // Throwing exception
}
return a / b;
}
int main() {
try {
cout << divide(10.0, 2.0) << endl;
cout << divide(5.0, 0.0) << endl; // Will throw
} catch (const invalid_argument &e) {
cerr << "Caught Exception: " << e.what() << endl;
} catch (...) {
cerr << "Caught Unknown Exception!" << endl;
}
return 0;
}
Exam questions
- [7 Marks] Explain the exception handling mechanism in C++ (try, catch, throw) with a divide-by-zero example.
- [7 Marks] What is stack unwinding during exception handling? How does C++ guarantee resource cleanup when an exception is thrown?