C++ program to show runtime exceptions
In this article, we will discuss a C++ program to show the runtime exceptions. But before going to its implementation, we need to know about runtime exceptions.
What are Runtime Exceptions?
Runtime exceptions are errors that occur during a program's execution, as opposed to compilation errors that are caught during the translation of code from human-readable form to machine code
Types of Runtime Exceptions:
Common types of runtime exceptions include:
- Division by zero
- Array out-of-bounds access
- Accessing deallocated memory (dangling pointers)
- Type mismatches
- File operations errors (e.g., trying to open a non-existent file)
- Exception Handling Mechanism
Handling runtime exceptions using the try-catch block:
try {
// Code that might throw an exception
} catch (exception_type1 &e) {
// Handle exception of type1
} catch (exception_type2 &e) {
// Handle exception of type2
} catch (...) { // Catch-all block for any exception
// Handle unexpected exceptions
}
- try block: It encloses the code that might potentially throw an exception.
- catch block: This block captures the thrown exception if its type matches the specified exception_type. The exception object (e) can be used to access information about the error. Multiple catch blocks can be used to handle different exception types.
- catch-all block (catch (...)): Catches any exception not handled by specific catch blocks. Use this method cautiously because it can mask unexpected errors.
Example:
Let us take an example to illustrate the Runtime Exceptions in C++.
#include <iostream>
using namespace std;
int main() {
int num1, num2, result;
// Division by zero (runtime exception)
try {
cout << "Enter two numbers: ";
cin >> num1 >> num2;
if (num2 == 0) {
throw runtime_error("Division by zero!"); // Throw a custom exception
}
result = num1 / num2;
cout << "Result: " << result << endl;
} catch (const runtime_error& e) {
cerr << "Error: " << e.what() << endl; // Access error message
} catch (...) {
cerr << "An unexpected exception occurred." << endl;
}
// Array out-of-bounds access (potential runtime exception)
try {
int arr[5] = {1, 2, 3, 4, 5};
cout << "Element at index 6: " << arr[6] << endl; // Out-of-bounds access
} catch (const out_of_range& e) { // Catch standard exception for array out-of-bounds
cerr << "Error: Array index out of bounds." << endl;
} catch (...) {
cerr << "An unexpected exception occurred." << endl; // Catch other potential exceptions
}
return 0;
}
Output:
![C++ program to show runtime exceptions/>
<!-- /wp:html -->
<!-- wp:paragraph -->
<p><strong>Explanation:</strong></p>
<!-- /wp:paragraph -->
<!-- wp:list -->
<ul class=](https://static.tutorialandexample.com/cpp/cpp-program-to-show-runtime-exceptions1.png)
Best Practices for Exception Handling:
1. Use Exceptions for Exceptional Circumstances
Exceptions should be used to handle exceptional circumstances, such as runtime errors, rather than for normal control flow. For example, a function expects a certain input but receives invalid data. In that case, it can throw an exception to indicate the error rather than relying on return codes or special values to indicate failure.
void processData(int value) {
if (value < 0) {
throw std::invalid_argument("Invalid input: value must be non-negative");
}
// Process the data
}
2. Be Specific in Catch Blocks
When catching exceptions, be as specific as possible in the catch blocks to handle different exception types appropriately. It allows us to provide specialized error handling for different types of exceptions.
try {
// Code that may throw exceptions
} catch (const std::invalid_argument& e) {
std::cerr << "Invalid argument: " << e.what() << std::endl;
} catch (const std::out_of_range& e) {
std::cerr << "Out of range: " << e.what() << std::endl;
} catch (const std::exception& e) {
// Catch any other exceptions
std::cerr << "Exception caught: " << e.what() << std::endl;
}
3. Use Catch-All Blocks Sparingly
While they can be useful for catching unexpected exceptions and preventing program crashes, indiscriminately catching all exceptions can mask critical errors and make it difficult to diagnose and fix problems in our code. Instead, prioritize providing specialized error handling for different types of exceptions.
try {
// Code that may throw exceptions
} catch (...) {
// Catch all exceptions
std::cerr << "An unexpected exception occurred." << std::endl;
}
4. Provide Informative Error Messages
When throwing exceptions, it provides informative error messages to help developers understand what went wrong. It can include relevant context information and data values.
throw std::runtime_error("Failed to open file: " + filename);
5. Re-Throw Exceptions When Necessary
If we cannot handle an exception within a specific scope, consider re-throwing the exception to propagate it to a higher level for handling. It allows exceptions to be caught and handled at an appropriate level in the program.
try {
// Code that may throw exceptions
} catch (const std::exception& e) {
// Handle the exception
throw; // Re-throw the exception
}
Conclusion:
In conclusion, by following these best practices for exception handling in C++, we can write more robust and maintainable code that effectively handles runtime errors and exceptions. Proper exception handling is essential for creating reliable and resilient software applications.