0% found this document useful (0 votes)
22 views19 pages

Module 5 C++

C++ notes for

Uploaded by

saicharanrolex
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views19 pages

Module 5 C++

C++ notes for

Uploaded by

saicharanrolex
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

C++ Exception Handling

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 exception
· throw - throws an exception when an error is detected
· catch - code that handles the exception thrown by the throw 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;
}
Run Code

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.
Working of try, throw, and catch statements in C++
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 our try...catch statement.
This is because this block catches all possible exceptions and acts
as the default catch 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;
}
Run Code

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.

Thrown by C++ when an attempt is made to perform a dynamic_cast to an inval


std::bad_cast
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.

Exception Handling in C++


Last Updated : 08 Mar, 2024
·
·
·
In C++, exceptions are runtime anomalies or abnormal conditions that a
program encounters during its execution. The process of handling these
exceptions is called exception handling. Using the exception handling
mechanism, the control from one part of the program where the exception
occurred can be transferred to another part of the code.
So basically using exception handling in C++, we can handle the exceptions
so that our program keeps running.
What is a C++ Exception?
An exception is an unexpected problem that arises during the execution of
a program our program terminates suddenly with some errors/issues.
Exception occurs during the running of the program (runtime).
Types of C++ Exception
There are two types of exceptions in C++
1. Synchronous: Exceptions that happen when something goes
wrong because of a mistake in the input data or when the program
is not equipped to handle the current type of data it’s working with,
such as dividing a number by zero.
2. Asynchronous: Exceptions that are beyond the program’s
control, such as disc failure, keyboard interrupts, etc.
C++ try and catch
C++ provides an inbuilt feature for Exception Handling. It can be done using
the following specialized keywords: try, catch, and throw with each having a
different purpose.
Syntax of try-catch in C++
try {
// Code that might throw an exception
throw SomeExceptionType("Error message");
}
catch( Exception Name e1 ) {
// catch block catches the exception that is thrown from try
block
}

1. try in C++
The try keyword represents a block of code that may throw an exception
placed inside the try block. It’s followed by one or more catch blocks. If an
exception occurs, try block throws that exception.
2. catch in C++
The catch statement represents a block of code that is executed when a
particular exception is thrown from the try block. The code to handle the
exception is written inside the catch block.
3. throw in C++
An exception in C++ can be thrown using the throw keyword. When a
program encounters a throw statement, then it immediately terminates the
current function and starts finding a matching catch block to handle the
thrown exception.
Note: Multiple catch statements can be used to catch different type of
exceptions thrown by try block.
The try and catch keywords come in pairs: We use the try block to test some
code and If the code throws an exception we will handle it in our catch block.
Why do we need Exception Handling in C++?
The following are the main advantages of exception handling over traditional
error handling:
1. Separation of Error Handling Code from Normal Code: There
are always if-else conditions to handle errors in traditional error
handling codes. These conditions and the code to handle errors
get mixed up with the normal flow. This makes the code less
readable and maintainable. With try/catch blocks, the code for
error handling becomes separate from the normal flow.

2. Functions/Methods can handle only the exceptions they


choose: A function can throw many exceptions, but may choose
to handle some of them. The other exceptions, which are thrown
but not caught, can be handled by the caller. If the caller chooses
not to catch them, then the exceptions are handled by the caller of
the caller.
In C++, a function can specify the exceptions that it throws using
the throw keyword. The caller of this function must handle the
exception in some way (either by specifying it again or catching it).

3. Grouping of Error Types: In C++, both basic types and objects


can be thrown as exceptions. We can create a hierarchy of
exception objects, group exceptions in namespaces or classes,
and categorize them according to their types.
Examples of Exception Handling in C++
The following examples demonstrate how to use a try-catch block to handle
exceptions in C++.
Example 1
The below example demonstrates throw exceptions in C++.
· C++

// C++ program to demonstate the use of try,catch and throw


// in exception handling.

#include <iostream>
#include <stdexcept>
using namespace std;

int main()
{
// try block
try {
int numerator = 10;
int denominator = 0;
int res;

// check if denominator is 0 then throw runtime


// error.
if (denominator == 0) {
throw runtime error (
"Division by zero not allowed!");
}

// calculate result if no exception occurs


res = numerator / denominator;
//[printing result after division
cout << "Result after division: " << res << endl;
}
// catch block to catch the thrown exception
catch (const exception& e) {
// print the exception
cout << "Exception " << e.what() << endl;
}

return 0;
}

Output
Exception Division by zero not allowed!
Example 2
The following is a simple example to show exception handling in C++. The
output of the program explains the flow of execution of try/catch blocks.
· CPP

// C++ program to demonstate the use of try,catch and throw


// in exception handling.

#include <iostream>
using namespace std;

int main()
{
int x = -1;

// Some code
cout << "Before try \n";

// try block
try {
cout << "Inside try \n";
if (x < 0) {
// throwing an exception
throw x;
cout << "After throw (Never executed) \n";
}
}

// catch block
catch (int x) {
cout << "Exception Caught \n";
}

cout << "After catch (Will be executed) \n";


return 0;
}

Output
Before try
Inside try
Exception Caught
After catch (Will be executed)

Properties of Exception Handling in C++


Property 1
There is a special catch block called the ‘catch-all’ block, written as
catch (…), that can be used to catch all types of exceptions.
Example
In the following program, an int is thrown as an exception, but there is no
catch block for int, so the catch (…) block will be executed.
· CPP

// C++ program to demonstrate the use of catch all


// in exception handling.

#include <iostream>
using namespace std;

int main()
{
// try block
try {

// throw
throw 10;
}

// catch block
catch (char* excp) {
cout << "Caught " << excp;
}

// catch all
catch (...) {
cout << "Default Exception\n";
}
return 0;
}

Output
Default Exception

Property 2
Implicit type conversion doesn’t happen for primitive types.
Example
In the following program, ‘a’ is not implicitly converted to int.
· CPP

//// C++ program to demonstrate property 2: Implicit type


/// conversion doesn't happen for primitive types.
// in exception handling.

#include <iostream>
using namespace std;

int main()
{
try {
throw 'a';
}
catch (int x) {
cout << "Caught " << x;
}
catch (...) {
cout << "Default Exception\n";
}
return 0;
}

Output
Default Exception

Output:
Default Exception

Property 3
If an exception is thrown and not caught anywhere, the program
terminates abnormally.
Example
In the following program, a char is thrown, but there is no catch block to catch
the char.
· CPP

// C++ program to demonstrate property 3: If an exception is


// thrown and not caught anywhere, the program terminates
// abnormally in exception handling.

#include <iostream>
using namespace std;

int main()
{
try {
throw 'a';
}
catch (int x) {
cout << "Caught ";
}
return 0;
}

Output
terminate called after throwing an instance of 'char'
We can change this abnormal termination behavior by writing our
unexpected function.
Note: A derived class exception should be caught before a base class
exception.
Like Java, the C++ library has a standard exception class which is the base
class for all standard exceptions. All objects thrown by the components of
the standard library are derived from this class. Therefore, all standard
exceptions can be caught by catching this type.
Property 4
Unlike Java, in C++, all exceptions are unchecked, i.e., the compiler
doesn’t check whether an exception is caught or not (See this for
details). So, it is not necessary to specify all uncaught exceptions in a
function declaration. However,exception-handling it’s a recommended
practice to do so.
Example
The following program compiles fine, but ideally, the signature of fun() should
list the unchecked exceptions.
· CPP

// C++ program to demonstate property 4 in exception


// handling.

#include <iostream>
using namespace std;

// This function signature is fine by the compiler, but not


// recommended. Ideally, the function should specify all
// uncaught exceptions and function signature should be
// "void fun(int *ptr, int x) throw (int *, int)"
void fun(int* ptr, int x)
{
if (ptr == NULL)
throw ptr;
if (x == 0)
throw x;
/* Some functionality */
}

int main()
{
try {
fun(NULL, 0);
}
catch (...) {
cout << "Caught exception from fun()";
}
return 0;
}

Output
Caught exception from fun()

A better way to write the above code:


· CPP

// C++ program to demonstate property 4 in better way

#include <iostream>
using namespace std;

// Here we specify the exceptions that this function


// throws.
void fun(int* ptr, int x) throw(
int*, int) // Dynamic Exception specification
{
if (ptr == NULL)
throw ptr;
if (x == 0)
throw x;
/* Some functionality */
}

int main()
{
try {
fun(NULL, 0);
}
catch (...) {
cout << "Caught exception from fun()";
}
return 0;
}

Output
Caught exception from fun()

Note: The use of Dynamic Exception Specification has been deprecated


since C++11. One of the reasons for it may be that it can randomly abort your
program. This can happen when you throw an exception of another type
which is not mentioned in the dynamic exception specification. Your program
will abort itself because in that scenario, it calls (indirectly) terminate(), which
by default calls abort().
Property 5
In C++, try/catch blocks can be nested. Also, an exception can be re-
thrown using “throw; “.
Example
The following program shows try/catch blocks nesting.
· CPP

// C++ program to demonstrate try/catch blocks can be nested


// in C++

#include <iostream>
using namespace std;

int main()
{

// nesting of try/catch
try {
try {
throw 20;
}
catch (int n) {
cout << "Handle Partially ";
throw; // Re-throwing an exception
}
}
catch (int n) {
cout << "Handle remaining ";
}
return 0;
}

Output
Handle Partially Handle remaining

A function can also re-throw a function using the same “throw; ” syntax. A
function can handle a part and ask the caller to handle the remaining.
Property 6
When an exception is thrown, all objects created inside the enclosing
try block are destroyed before the control is transferred to the catch
block.
Example
The following program demonstrates the above property.
· CPP

// C++ program to demonstrate

#include <iostream>
using namespace std;

// Define a class named Test


class Test {
public:
// Constructor of Test
Test() { cout << "Constructor of Test " << endl; }
// Destructor of Test
~Test() { cout << "Destructor of Test " << endl; }
};

int main()
{
try {
// Create an object of class Test
Test t1;

// Throw an integer exception with value 10


throw 10;
}
catch (int i) {
// Catch and handle the integer exception
cout << "Caught " << i << endl;
}
}

Output
Constructor of Test
Destructor of Test
Caught 10

Limitations of Exception Handling in C++


The exception handling in C++ also have few limitations:
· Exceptions may break the structure or flow of the code as multiple
invisible exit points are created in the code which makes the code
hard to read and debug.
· If exception handling is not done properly can lead to resource
leaks as well.
· It’s hard to learn how to write Exception code that is safe.
· There is no C++ standard on how to use exception handling,
hence many variations in exception-handling practices exist.
Conclusion
Exception handling in C++ is used to handle unexpected happening using
“try” and “catch” blocks to manage the problem efficiently. This exception
handling makes our programs more reliable as errors at runtime can be
handled separately and it also helps prevent the program from crashing and
abrupt termination of the program when error is encountered.

You might also like