An exception is an unexpected event that occurs during program execution. For example,
divide_by_zero = 7 / 0;
The above code causes an exception as it is not possible to divide a number by 0.
The process of handling these types of errors in C++ is known as exception handling.
In C++, we handle exceptions with the help of the try
and catch
blocks, along with the throw
keyword.
try
- code that may raise an exceptionthrow
- throws an exception when an error is detectedcatch
- code that handles the exception thrown by thethrow
keyword
Note: The throw
statement is not compulsory, especially if we use standard C++ exceptions.
Syntax for Exception Handling in C++
The basic syntax for exception handling in C++ is given below:
try {
// code that may raise an exception
throw argument;
}
catch (exception) {
// code to handle exception
}
Here, we have placed the code that might generate an exception inside the try
block. Every try
block is followed by the catch
block.
When an exception occurs, the throw
statement throws an exception, which is caught by the catch
block.
The catch
block cannot be used without the try
block.
Example 1: C++ Exception Handling
// program to divide two numbers
// throws an exception when the divisor is 0
#include <iostream>
using namespace std;
int main() {
double numerator, denominator, divide;
cout << "Enter numerator: ";
cin >> numerator;
cout << "Enter denominator: ";
cin >> denominator;
try {
// throw an exception if denominator is 0
if (denominator == 0)
throw 0;
// not executed if denominator is 0
divide = numerator / denominator;
cout << numerator << " / " << denominator << " = " << divide << endl;
}
catch (int num_exception) {
cout << "Error: Cannot divide by " << num_exception << endl;
}
return 0;
}
Output 1
Enter numerator: 72 Enter denominator: 0 Error: Cannot divide by 0
Output 2
Enter numerator: 72 Enter denominator: 3 72 / 3 = 24
The above program divides two numbers and displays the result. But an exception occurs if the denominator is 0.
To handle the exception, we have put the code divide = numerator / denominator;
inside the try block. Now, when an exception occurs, the rest of the code inside the try
block is skipped.
The catch
block catches the thrown exception and executes the statements inside it.
If none of the statements in the try
block generates an exception, the catch
block is skipped.
Notice that we have thrown the int
literal 0 with the code throw 0;
.
We can throw any literal or variable or class, depending on the situation and depending on what we want to execute inside the catch
block.
The catch
parameter int num_exception
takes the value passed by the throw
statement i.e. the literal 0.
Catching All Types of Exceptions
In exception handling, it is important that we know the types of exceptions that can occur due to the code in our try
statement.
This is so that we can use the appropriate catch
parameters. Otherwise, the try...catch
statements might not work properly.
If we do not know the types of exceptions that can occur in our try
block, then we can use the ellipsis symbol ...
as our catch
parameter.
try {
// code
}
catch (...) {
// code
}
C++ Multiple catch Statements
In C++, we can use multiple catch
statements for different kinds of exceptions that can result from a single block of code.
try {
// code
}
catch (exception1) {
// code
}
catch (exception2) {
// code
}
catch (...) {
// code
}
Here, our program catches exception1
if that exception occurs. If not, it will catch exception2
if it occurs.
If there is an error that is neither exception1
nor exception2
, then the code inside of catch (...) {}
is executed.
Notes:
catch (...) {}
should always be the final block in ourtry...catch
statement. This is because this block catches all possible exceptions and acts as the defaultcatch
block.
- It is not compulsory to include the default
catch
block in our code.
Example 2: C++ Multiple catch Statements
This program divides two numbers and stores the result in an array element. There are two possible exceptions that can occur in this program:
- If the array is out of bounds i.e. if the index of the array is greater than the size of the array
- If a number is divided by 0
These exceptions are caught in multiple catch
statements.
#include <iostream>
using namespace std;
int main() {
double numerator, denominator, arr[4] = {0.0, 0.0, 0.0, 0.0};
int index;
cout << "Enter array index: ";
cin >> index;
try {
// throw exception if array out of bounds
if (index >= 4)
throw "Error: Array out of bounds!";
// not executed if array is out of bounds
cout << "Enter numerator: ";
cin >> numerator;
cout << "Enter denominator: ";
cin >> denominator;
// throw exception if denominator is 0
if (denominator == 0)
throw 0;
// not executed if denominator is 0
arr[index] = numerator / denominator;
cout << arr[index] << endl;
}
// catch "Array out of bounds" exception
catch (const char* msg) {
cout << msg << endl;
}
// catch "Divide by 0" exception
catch (int num) {
cout << "Error: Cannot divide by " << num << endl;
}
// catch any other exception
catch (...) {
cout << "Unexpected exception!" << endl;
}
return 0;
}
Output 1
Enter array index: 5 Error: Array out of bounds!
Here, the array arr only has 4 elements. So, index cannot be greater than 3.
In this case, index is 5. So we throw a string literal "Error: Array out of bounds!"
. This exception is caught by the first catch
block.
Notice the catch
parameter const char* msg
. This indicates that the catch
statement takes a string
literal as an argument.
Output 2
Enter array index: 2 Enter numerator: 5 Enter denominator: 0 Error: Cannot divide by 0
Here, the denominator is 0. So we throw the int
literal 0. This exception is caught by the second catch
block.
If any other exception occurs, it is caught by the default catch
block.
Output 3
Enter array index: 2 Enter numerator: 5 Enter denominator: 2 2.5
Here, the program runs without any problem as no exception occurs.
C++ Standard Exception
C++ has provided us with a number of standard exceptions that we can use in our exception handling. Some of them are shown in the table below.
Exception | Description |
---|---|
std::exception |
The parent class of all C++ exceptions. |
std::bad_alloc |
Thrown when a dynamic memory allocation fails. |
std::bad_cast |
Thrown by C++ when an attempt is made to perform a dynamic_cast to an invalid type. |
std::bad_exception |
Typically thrown when an exception is thrown and it cannot be rethrown. |
There are many other standard exceptions in C++.
These exceptions are defined in the exception
header file.
To learn more, visit our C++ Standard Exceptions tutorial.