How Does Exception Handling Work in C++?
Understand C++ exception handling with try, throw, and catch, plus stack unwinding, RAII cleanup, the std::exception hierarchy, and exception safety.
Expected Interview Answer
Exception handling in C++ separates error detection from error handling using try, throw, and catch: code that may fail runs inside a try block, throws an exception object on error, and a matching catch block handles it.
When 'throw' is executed, the runtime unwinds the stack, destroying local objects (calling their destructors) until it finds a catch block whose type matches the thrown object. This RAII-driven unwinding is what makes exceptions safe. Catch blocks are matched top-to-bottom by type; a catch(...) handles anything. Standard exceptions derive from std::exception, and best practice is to throw by value and catch by const reference. Functions can be marked 'noexcept' to promise they will not throw.
- Separates error handling from normal logic
- Automatic cleanup via stack unwinding and destructors
- Propagates errors up the call stack cleanly
- Rich error info through exception objects
- Enables strong exception-safety guarantees with RAII
AI Mentor Explanation
When a batter is given out, play does not silently continue — the umpire raises a finger (throws), the batter leaves, and the next in line comes on to handle the situation. Exception handling works the same way: throw signals the failure, normal flow stops, and the nearest matching catch block takes over the response.
Step-by-Step Explanation
Step 1
Wrap risky code
Put operations that might fail inside a try block.
Step 2
Throw on error
Use 'throw' with an exception object, ideally derived from std::exception, when a fault is detected.
Step 3
Unwind the stack
The runtime destroys local objects (running destructors) as it searches upward for a handler.
Step 4
Match a catch
Catch blocks are checked top-to-bottom by type; catch by const reference to avoid slicing.
Step 5
Recover or rethrow
Handle the error, or use a bare 'throw;' inside catch to rethrow it to an outer handler.
What Interviewer Expects
- Understanding of try, throw, and catch mechanics
- Knowledge of stack unwinding and RAII cleanup
- Catching by const reference, throwing by value
- Familiarity with std::exception hierarchy
- Awareness of noexcept and exception safety
Common Mistakes
- Catching exceptions by value (causing slicing)
- Throwing raw pointers or using new to throw
- Using exceptions for ordinary control flow
- Letting a destructor throw an exception
- Ordering catch(...) before more specific handlers
Best Answer (HR Friendly)
“Exception handling is C++'s way of dealing with errors gracefully: risky code goes in a 'try' block, and if something goes wrong it 'throws' a problem that a matching 'catch' block picks up and handles, so the program can recover instead of crashing.”
Code Example
#include <iostream>
#include <stdexcept>
double divide(double a, double b) {
if (b == 0.0)
throw std::invalid_argument("division by zero");
return a / b;
}
int main() {
try {
std::cout << divide(10, 2) << '\n';
std::cout << divide(5, 0) << '\n';
} catch (const std::invalid_argument& e) {
std::cerr << "Error: " << e.what() << '\n';
} catch (...) {
std::cerr << "Unknown error\n";
}
return 0;
}Follow-up Questions
- What is stack unwinding and how does RAII make it safe?
- Why should you catch exceptions by const reference?
- What happens if an exception escapes a noexcept function?
- Why must destructors not throw exceptions?
- What is the difference between the strong and basic exception-safety guarantees?
MCQ Practice
1. Which keyword raises an exception in C++?
The throw keyword raises an exception object that is then matched against catch handlers.
2. How should you generally catch exceptions to avoid object slicing?
Catching by const reference preserves the dynamic type and avoids copying/slicing the exception object.
3. During stack unwinding, what happens to local objects?
Stack unwinding runs destructors for fully constructed local objects, enabling RAII-based cleanup.
Flash Cards
What three keywords drive C++ exceptions? — try (guarded code), throw (raise error), catch (handle error).
What is stack unwinding? — Destroying local objects and calling their destructors as the runtime searches up the stack for a handler.
How should exceptions be thrown and caught? — Throw by value, catch by const reference to avoid slicing.
What does noexcept mean? — A promise a function will not throw; if it does, std::terminate is called.