Loading lessons...
Exceptions (why we need them)
Exceptions (why we need them)
An exception is an event that happens while a program runs and interrupts the normal flow of the program, such as an attempt to divide by zero or an out-of-range index.
An example
try {
int age = 15;
if (age >= 18) {
cout << "Access granted - you are old enough.";
} else {
throw (age);
}
}
catch (int myNum) {
cout << "Access denied - you must be at least 18. ";
cout << "Age is: " << myNum;
}
When the age is under 18, the throw raises an exception, and the catch block picks it up and handles it gracefully. The program keeps running instead of crashing.
The problem with error codes
Before exceptions, C++ functions signaled failure by returning special values: a negative number, a bool, a nullptr. Each caller had to test the returned value manually on every line.
int divide(int a, int b, bool& ok) {
if (b == 0) { ok = false; return 0; }
ok = true;
return a / b;
}
bool ok;
int r = divide(10, 0, ok); // check every call site
if (!ok) { cout << "failed"; }
You can see the problem immediately: the error code chains, checking the return of every call makes the code crowded, and a forgotten check silently passes garbage on.
What exceptions give you
Exceptions break the chain. A function that fails can throw, and a catch block anywhere up the call chain handles the error, without threading a success bool through every layer. Divide-by-zero is the classic trigger: instead of silently returning junk, the problem is loud and localizable.
- The compiler finds syntax errors right away.
- Exceptions must be stated as loud problems.
- The happy path stays clean; the machinery moves elsewhere.
TL;DR
- An exception is an event that interrupts the normal run of a program.
- Dividing by zero is the classic example of such an event.
- Error codes force a check at every call site and get messy fast.
- A thrown exception skips the rest of the try block.
- Exceptions let one catch handle errors from many layers of calls.