0% found this document useful (0 votes)
21 views28 pages

OOP Chapter 10 Exception Handling

Chapter 10 discusses exception handling in C++, which is a structured mechanism for managing runtime errors through constructs like try, catch, and throw. It highlights the advantages of exception handling over conventional error handling methods, such as improved readability, centralized error management, and the ability to handle various error types. The chapter also covers specific techniques for error handling, including return codes, error flags, and assertions, emphasizing the importance of robust error management in programming.

Uploaded by

niteshray030
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)
21 views28 pages

OOP Chapter 10 Exception Handling

Chapter 10 discusses exception handling in C++, which is a structured mechanism for managing runtime errors through constructs like try, catch, and throw. It highlights the advantages of exception handling over conventional error handling methods, such as improved readability, centralized error management, and the ability to handle various error types. The chapter also covers specific techniques for error handling, including return codes, error flags, and assertions, emphasizing the importance of robust error management in programming.

Uploaded by

niteshray030
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/ 28

CHAPTER 10

Exception Handling
TABLE OF CONTENTS

10 Exception Handling 1
10.1 Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . 1
10.2 Exception Handling Constructs (try, catch, throw) 4
10.3 Advantage over Conventional Error Handling . . . 7
10.4 Multiple Exception Handling . . . . . . . . . . . . . . . 11
10.5 Rethrowing Exception . . . . . . . . . . . . . . . . . . . . . 15
10.6 Catching All Exceptions . . . . . . . . . . . . . . . . . . . 17
10.7 Exception with Arguments . . . . . . . . . . . . . . . . . 18
10.8 Exceptions Specification for Function . . . . . . . . . . 20
10.8.1 Dynamic Exception Specification (Deprecated) 20
10.8.2 Noexcept Specification . . . . . . . . . . . . . . . . . 21
10.9 Handling Uncaught and Unexpected Exceptions . 22
10.9.1 Uncaught Exceptions . . . . . . . . . . . . . . . . . . 23
10.9.2 Unexpected Exceptions . . . . . . . . . . . . . . . . 24

i
Chapter 10

Exception Handling

Exception handling in C++ is a mechanism used to manage runtime errors or excep-


tional conditions that may occur during program execution. It provides a structured
way to handle unexpected situations, allowing developers to write robust and reliable
code. Exception handling involves three main components: try, catch, and throw.

Exception handling provides several advantages over traditional error handling mech-
anisms, including separation of error-handling code from normal code, centralized
error handling, and the ability to propagate errors up the call stack until they are
handled. It promotes cleaner and more maintainable code by allowing developers to
focus on normal program logic and handling unexpected situations separately.

10.1 Error Handling

Error handling in C++ refers to the process of managing and responding to runtime
errors or exceptional conditions that may occur during program execution. Unlike
exceptions, which are used to handle exceptional circumstances, error handling typi-
cally involves detecting and responding to expected errors or failures in the program’s
execution. Error handling in C++ can be accomplished through various techniques,
such as return codes, error flags, and assertions. Let’s explore some common methods
of error handling in C++:

1. Return Codes:
Functions in C++ can return special values, known as return codes, to indicate
success or failure. Conventionally, a function returns 0 to indicate success and
a non-zero value to indicate failure.
2

Example:

#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
int divide ( int x , int y) {
i f ( y == 0 ) {
r e t u r n −1; // E r r o r : D i v i s i o n by z e r o
}
r e t u r n x / y ; // S u c c e s s
}

i n t main ( ) {
int r e s u l t = divide (10 , 0);
i f ( r e s u l t == −1) {
c e r r << ” E r r o r : D i v i s i o n by z e r o ” <<
endl ;
} else {
cout << ” R e s u l t : ” << r e s u l t << e n d l ;
}
return 0;
}
Output :
E r r o r : D i v i s i o n by z e r o

2. Error Flags:
Functions can set error flags or status variables to indicate errors. The caller
then checks these flags to determine if an error occurred.

Example:

#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
b o o l d i v i d e ( i n t x , i n t y , i n t& r e s u l t ) {
i f ( y == 0 ) {
r e t u r n f a l s e ; // E r r o r : D i v i s i o n by z e r o
}

© iamsspoudel
3

r e s u l t = x / y ; // S u c c e s s
return true ;
}

i n t main ( ) {
int result ;
i f ( ! divide (10 , 0 , r e s u l t )) {
c e r r << ” E r r o r : D i v i s i o n by z e r o ” << e n d l ;
} else {
cout << ” R e s u l t : ” << r e s u l t << e n d l ;
}
return 0;
}
Output :
E r r o r : D i v i s i o n by z e r o

3. Assertions:
Assertions are statements that check for conditions that should always be true
during program execution. If an assertion fails, it indicates a programming error
and terminates the program.

Example:

#i n c l u d e <c a s s e r t >
#i n c l u d e <i o s t r e a m >

int divide ( int x , int y) {


a s s e r t ( y != 0 ) ; // A s s e r t i o n : y s h o u l d not be z e r o
return x / y ;
}

i n t main ( ) {
int r e s u l t = divide (10 , 0);
s t d : : cout << ” R e s u l t : ” << r e s u l t << s t d : : e n d l ;
return 0;

© iamsspoudel
4

}
Output :
A s s e r t i o n f a i l e d : y != 0

Summary:

Error handling in C++ involves various techniques, including return codes, error
flags, and assertions. Each method has its advantages and use cases, depending on
the nature of the program and the types of errors expected. Proper error handling is
essential for writing reliable and robust C++ programs, ensuring that they gracefully
handle unexpected situations and provide meaningful feedback to users.

10.2 Exception Handling Constructs (try, catch, throw)

Exception handling in C++ revolves around three main constructs: try, catch, and
throw. These constructs provide a structured way to handle runtime errors or excep-
tional conditions that may occur during program execution.

Exception Handling Constructs

• try: The block of code that is monitored for exceptions.

• catch: The block of code that handles the exception.

• throw: Used to signal the occurrence of an exception.

1. try Block: The try block encloses the code that may potentially throw an
exception. It identifies the region of code where exceptions are anticipated.

Syntax:

try {
// Code t h a t may throw an e x c e p t i o n
} c a t c h ( ExceptionType1& e1 ) {
// Handler f o r ExceptionType1
} c a t c h ( ExceptionType2& e2 ) {
// Handler f o r ExceptionType2
} catch ( . . . ) {

© iamsspoudel
5

// Handler f o r any o t h e r e x c e p t i o n s
}

Example:

#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
i n t main ( )
{
try {
// Code t h a t may throw an e x c e p t i o n
throw r u n t i m e e r r o r ( ”An e r r o r o c c u r r e d ” ) ;
} c a t c h ( c o n s t e x c e p t i o n& e ) {
// Handle t h e e x c e p t i o n
c e r r << ” E xce pt ion caught : ” << e . what ( ) <<
endl ;
}
return 0;
}
Output :
E x c e p ti on caught : An e r r o r o c c u r r e d

2. catch Block: The catch block is used to catch and handle exceptions thrown
by the corresponding try block. It specifies the type of exception it can handle
and contains the code to handle the exception.

Syntax:

c a t c h ( ExceptionType& e ) {
// Handler f o r t h e e x c e p t i o n
}

Example:

try {
// Code t h a t may throw an e x c e p t i o n
throw r u n t i m e e r r o r ( ”An e r r o r o c c u r r e d ” ) ;

© iamsspoudel
6

} c a t c h ( c o n s t s t d : : r u n t i m e e r r o r& e ) {
// Handle t h e r u n t i m e e r r o r e x c e p t i o n
c e r r << ”Runtime e r r o r caught : ” << e . what ( ) << e n d l ;
} catch ( . . . ) {
// Handle o t h e r t y p e s o f e x c e p t i o n s
c e r r << ”Unknown e r r o r caught ” << e n d l ;
}

3. throw Statement: The throw statement is used to manually raise an exception


within the try block. It can throw any object, including built-in types, pointers,
or class objects.

Syntax:

throw ExceptionType ( arguments ) ;

Example:

try {
// Code t h a t may throw an e x c e p t i o n
int x = 10;
i f ( x > 5)
{
throw ”x i s t oo l a r g e ” ;
}
} c a t c h ( c o n s t ch ar ∗ message )
{
// Handle t h e e x c e p t i o n
c e r r << ” E xce p t ion caught : ”<< message <<e n d l ;
}

Exception handling in C++ allows you to gracefully handle errors, providing a struc-
tured approach to dealing with unexpected situations. It separates error-handling
logic from normal code, making the program more robust and maintainable.

Combined Program:

#i n c l u d e <i o s t r e a m >

© iamsspoudel
7

#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
void divide ( i n t a , i n t b) {
i f ( b == 0 ) {
throw i n v a l i d a r g u m e n t ( ” D i v i s i o n by z e r o ! ” ) ;
}
c o u t << a / b << e n d l ;
}

i n t main ( ) {
try {
divide (10 , 0);
} c a t c h ( c o n s t i n v a l i d a r g u m e n t &e ) {
c e r r << ” Caught e x c e p t i o n : ” << e . what ( ) << e n d l ;
}
return 0;
}
Output :
Caught e x c e p t i o n : D i v i s i o n by z e r o !

10.3 Advantage over Conventional Error Handling

Exception handling in C++ offers several advantages over conventional error handling
methods like return codes or error flags.

Advantages over Conventional Error Handling

• Readability and Maintenance: Exception handling separates error handling


code from regular code, making it easier to read and maintain.

• Propagating Errors: Exceptions can propagate up the call stack, allowing cen-
tralized error handling.

• Handling Different Types of Errors: Different catch blocks can handle different
types of errors.

© iamsspoudel
8

Let’s illustrate these advantages with an example:

1. Separation of Concerns:
With exception handling, error-handling code is separated from the main logic
of the program. This separation enhances code readability and maintainability
by isolating error-handling logic in catch blocks.

Example:

Consider a function that reads data from a file. With exception handling, error
handling code is separated from the file reading logic.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <f s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
v o i d r e a d F i l e ( c o n s t s t r i n g& f i l e n a m e ) {
ifstream f i l e ( filename ) ;
i f (! f i l e . is open ()) {
throw r u n t i m e e r r o r ( ” F a i l e d t o open f i l e ” ) ;
}

// Read data from t he f i l e


// . . .
}

i n t main ( ) {
try {
r e a d F i l e ( ” data . t x t ” ) ;
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r : ” << e . what ( ) << e n d l ;
}
return 0;
}
Output :
E r r o r : F a i l e d t o open f i l e

© iamsspoudel
9

2. Centralized Error Handling:


Exception handling allows for centralized error handling using catch blocks.
This centralization simplifies error handling and ensures consistent error han-
dling across the program.

Example:
Multiple functions may call readFile(), and they can all handle exceptions in a
centralized manner.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <f s t r e a m >
#i n c l u d e <s t d e x c e p t >

u s i n g namespace s t d ;

v o i d r e a d F i l e ( c o n s t s t r i n g& f i l e n a m e ) {
ifstream f i l e ( filename ) ;
if (! file ) {
throw r u n t i m e e r r o r ( ” F a i l e d t o open f i l e : ” + f i l e n a m e ) ;
}
// Read and p r o c e s s t he f i l e (dummy rea d f o r d e m o n s t r a t i o n )
string line ;
while ( g e t l i n e ( f i l e , l i n e )) {
cout << l i n e << e n d l ;
}
}

void processData ( ) {
try {
r e a d F i l e ( ” data . t x t ” ) ;
// P r o c e s s t he data
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r p r o c e s s i n g data : ” << e . what ( ) << e n d l ;
}
}

© iamsspoudel
10

i n t main ( ) {
try {
processData ( ) ;
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r i n main ( ) : ” << e . what ( ) << e n d l ;
}
return 0;
}

3. Propagation of Errors:
Exceptions can propagate up the call stack until they are caught, allowing er-
rors to be handled at higher levels of abstraction. This propagation mechanism
simplifies error handling and prevents the need for error checks at each inter-
mediate function call.

Example:
If an error occurs in readFile(), the exception can propagate up to the appro-
priate catch block.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <f s t r e a m >
#i n c l u d e <s t d e x c e p t >

u s i n g namespace s t d ;

// Function t o read t h e f i l e and p o t e n t i a l l y throw an e x c e p t i o n


v o i d r e a d F i l e ( c o n s t s t r i n g& f i l e n a m e ) {
ifstream f i l e ( filename ) ;
if (! file ) {
throw r u n t i m e e r r o r ( ” F a i l e d t o open f i l e : ” + f i l e n a m e ) ;
}
// Dummy read f o r d e m o n s t r a t i o n p u r p o s e s
string line ;
while ( g e t l i n e ( f i l e , l i n e )) {

© iamsspoudel
11

cout << l i n e << e n d l ;


}
}

// Function t o p r o c e s s t h e f i l e
void p r o c e s s F i l e ( ) {
try {
r e a d F i l e ( ” data . t x t ” ) ;
// P r o c e s s t he f i l e data
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r p r o c e s s i n g f i l e : ” << e . what ( ) << e n d l ;
}
}

i n t main ( ) {
try {
processFile ();
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r i n main ( ) : ” << e . what ( ) << e n d l ;
}
return 0;
}

In summary, exception handling in C++ provides a cleaner, more centralized, and


robust approach to error handling compared to conventional methods. It separates
error-handling concerns, centralizes error-handling logic, and allows errors to propa-
gate up the call stack, leading to more maintainable and reliable code.

10.4 Multiple Exception Handling

Multiple exception handling in C++ allows you to handle different types of exceptions
within the same try block. This enables you to provide specialized handling for various
exceptional situations that may arise during program execution. Here’s how multiple
exception handling works:

© iamsspoudel
12

Syntax:

try {
// Code t h a t may throw e x c e p t i o n s
} c a t c h ( ExceptionType1& e1 ) {
// Handler f o r ExceptionType1
} c a t c h ( ExceptionType2& e2 ) {
// Handler f o r ExceptionType2
} catch ( . . . ) {
// D e f a u l t h a n d l e r f o r any o t h e r e x c e p t i o n s
}

In this syntax:

• The try block contains the code that may throw exceptions.

• Each catch block specifies a different type of exception it can handle.

• You can have multiple catch blocks to handle different types of exceptions.

• The ellipsis (...) catches any other exceptions that are not caught by the pre-
ceding catch blocks.

Example:
Let’s demonstrate multiple exception handling with an example where we perform
division and handle specific exceptions for division by zero and other arithmetic errors.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;

i n t d i v i d e ( i n t dividend , i n t d i v i s o r ) {
i f ( d i v i s o r == 0 ) {
throw i n v a l i d a r g u m e n t ( ” D i v i s i o n by z e r o ” ) ;
}
return dividend / d i v i s o r ;
}

© iamsspoudel
13

i n t main ( ) {
try {
int r e s u l t = divide (10 , 0);
cout << ” R e s u l t : ” << r e s u l t << e n d l ;
} c a t c h ( c o n s t i n v a l i d a r g u m e n t& e ) {
c e r r << ” I n v a l i d argument : ” << e . what ( )
<< e n d l ;
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ”Runtime e r r o r : ” << e . what ( ) << e n d l ;
} catch ( . . . ) {
c e r r << ”Unknown e r r o r o c c u r r e d ” << e n d l ;
}
return 0;
}

In this example:

• The try block attempts to perform division, which may throw exceptions.

• The first catch block handles std::invalid argument, which occurs if division by
zero is attempted.

• The second catch block handles std::runtime error, which represents other arith-
metic errors.

• The third catch block catches any other unexpected exceptions that may occur.

Example 2

#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >

u s i n g namespace s t d ;

// Function t h a t throws d i f f e r e n t t y p e s o f e x c e p t i o n s
void testFunction ( i n t value ) {
i f ( v a l u e == 0 ) {
throw r u n t i m e e r r o r ( ” Runtime e r r o r : v a l u e i s z e r o ” ) ;

© iamsspoudel
14

} e l s e i f ( v a l u e == 1 ) {
throw l o g i c e r r o r ( ” L o g i c e r r o r : v a l u e i s one ” ) ;
} e l s e i f ( v a l u e == 2 ) {
throw i n v a l i d a r g u m e n t ( ” I n v a l i d argument : v a l u e i s two ” ) ;
} else {
cout << ” Value i s ” << v a l u e << e n d l ;
}
}

i n t main ( ) {
i n t values [ ] = {0 , 1 , 2 , 3};

f o r ( int value : values ) {


try {
testFunction ( value ) ;
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” Caught a r u n t i m e e r r o r : ” << e . what ( ) << e n d l ;
} c a t c h ( c o n s t l o g i c e r r o r& e ) {
c e r r << ” Caught a l o g i c e r r o r : ”<< e . what()<< e n d l ;
} c a t c h ( c o n s t i n v a l i d a r g u m e n t& e ) {
c e r r << ” Caught an i n v a l i d a r g u m e n t :”<< e . what()<< e n d l ;
} catch ( . . . ) {
c e r r << ” Caught an unknown e x c e p t i o n ” << e n d l ;
}
}

return 0;
}

By utilizing multiple exception handlers, you can provide targeted handling for differ-
ent types of exceptions, enhancing the robustness and reliability of your error handling
mechanism.

© iamsspoudel
15

10.5 Rethrowing Exception

Rethrowing an exception in C++ involves catching an exception in one part of the


code and then throwing it again from another part, typically after performing some
additional processing or logging. This mechanism is useful for propagating exceptions
up the call stack while allowing for intermediate processing. Here’s how it works:

Syntax:

try {
// Code t h a t may throw e x c e p t i o n s
} c a t c h ( ExceptionType& e ) {
// A d d i t i o n a l p r o c e s s i n g o r l o g g i n g
// Rethrow t h e e x c e p t i o n
throw ;
}

In this syntax:

• The try block contains the code that may throw exceptions.

• The catch block catches the exception and performs additional processing or
logging.

• The throw; statement is used to rethrow the caught exception, propagating it


up the call stack.

Example:

Let’s illustrate rethrowing an exception with an example where we open a file and
handle file opening errors. If the file cannot be opened, we log an error message and
rethrow the exception for higher-level handling.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >

u s i n g namespace s t d ;

// Function t h a t throws an e x c e p t i o n
v o i d r e a d F i l e ( c o n s t s t r i n g& f i l e n a m e ) {

© iamsspoudel
16

i f ( f i l e n a m e == ” ”) {
throw r u n t i m e e r r o r ( ” Filename cannot be empty ” ) ;
}
// S i m u l a t i n g f i l e read o p e r a t i o n
cout << ” Reading f i l e : ” << f i l e n a m e << e n d l ;
}

// Function t h a t h a n d l e s th e e x c e p t i o n and r e t h r o w s i t
v o i d p r o c e s s F i l e ( c o n s t s t r i n g& f i l e n a m e ) {
try {
readFile ( filename ) ;
// P r o c e s s t he f i l e data
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r i n p r o c e s s F i l e : ” << e . what ( ) << e n d l ;
throw ; // Rethrow t he caught e x c e p t i o n
}
}

i n t main ( ) {
try {
processFile (””);
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” Caught i n main : ” << e . what ( ) << e n d l ;
}
return 0;
}
Output :
E r r o r i n p r o c e s s F i l e : Filename cannot be empty
Caught i n main : Filename cannot be empty

Rethrowing exceptions allows for intermediate processing or logging of exceptions


while still propagating them up the call stack for higher-level handling. This mech-
anism helps maintain the separation of concerns and enhances error reporting and
handling capabilities.

© iamsspoudel
17

10.6 Catching All Exceptions

Catching all exceptions in C++ involves using a catch block that catches any ex-
ception, regardless of its type. This can be achieved by using an ellipsis (...) as the
exception type in the catch block. Catching all exceptions is useful when you want
to provide a generic error-handling mechanism that can handle any unexpected ex-
ception that may occur. Here’s how it works:

Syntax:

try {
// Code t h a t may throw e x c e p t i o n s
} catch ( . . . ) {
// Handler f o r any type o f e x c e p t i o n
}

In this syntax:

• The try block contains the code that may throw exceptions.

• The catch (...) block catches any type of exception that is thrown within the
try block.

Example:

Let’s illustrate catching all exceptions with an example where we attempt to perform
division. We’ll catch any exceptions that may occur during the division operation
using a catch-all block.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
i n t main ( ) {
try {
int dividend = 10;
int divisor = 0;

i f ( d i v i s o r == 0 ) {
throw r u n t i m e e r r o r ( ” D i v i s i o n by z e r o e r r o r ” ) ;

© iamsspoudel
18

int r e s u l t = dividend / d i v i s o r ;
cout << ” R e s u l t : ” << r e s u l t << e n d l ;
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” Caught a r u n t i m e e r r o r : ” << e . what ( ) << e n d l ;
} catch ( . . . ) {
c e r r << ”An unknown e r r o r o c c u r r e d ” << e n d l ;
}

return 0;
}

Catching all exceptions can be useful in scenarios where you want to provide a generic
error-handling mechanism that can handle unexpected errors gracefully. However, it’s
important to use it judiciously, as it may mask specific exceptions and make debugging
more difficult.

10.7 Exception with Arguments

In C++, exceptions can carry additional information by passing arguments when


throwing them. This enables the throwing code to provide more context about the
error that occurred, allowing the catching code to handle the exception more effec-
tively. Here’s how to throw exceptions with arguments:

Syntax for Throwing Exceptions with Arguments:

throw ExceptionType ( arguments ) ;

In this syntax:

• ExceptionType is the type of exception being thrown.

• arguments are any additional arguments passed to the exception constructor,


providing context about the error.

Example:

Let’s create a custom exception class FileOpenError that takes a filename as an

© iamsspoudel
19

argument when thrown. We’ll use this to demonstrate throwing exceptions with
arguments when a file cannot be opened.

#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
#i n c l u d e <s t r i n g >

u s i n g namespace s t d ;

// Custom e x c e p t i o n f o r f i l e opening e r r o r s
c l a s s FileOpenError : public runtime error {
public :
F i l e O p e n E r r o r ( c o n s t s t r i n g& f i l e n a m e )
: r u n t i m e e r r o r ( ” F a i l e d t o open f i l e : ” + f i l e n a m e ) {}
};

// Function t o open a f i l e
v o i d o p e n F i l e ( c o n s t s t r i n g& f i l e n a m e ) {
// S i m u l a t i n g f i l e open f a i l u r e
bool fileOpenFailed = true ;
// Replace with a c t u a l f i l e opening l o g i c

i f ( fileOpenFailed ) {
throw F i l e O p e n E r r o r ( f i l e n a m e ) ;
}
}

i n t main ( ) {
s t r i n g f i l e n a m e = ” example . t x t ” ;

try {
openFile ( filename ) ;
} c a t c h ( c o n s t F i l e O p e n E r r o r& e ) {
c e r r << ” E r r o r : ” << e . what ( ) << e n d l ;

© iamsspoudel
20

return 0;
}

Throwing exceptions with arguments allows you to provide detailed information about
errors, making it easier to diagnose and handle them appropriately in the catching
code.

10.8 Exceptions Specification for Function

In C++, exception specifications for functions are used to declare the types of excep-
tions that a function may throw. This provides information to callers of the function
about the exceptional situations they need to handle. There are two types of excep-
tion specifications: dynamic and noexcept.

r e t u r n t y p e f u n c t i o n n a m e ( p a r a m e t e r l i s t ) throw ( e x c e p t i o n l i s t ) ;

v o i d f u n c 1 ( ) ; // throw any e x c e p t i o n
v o i d f u n c 2 ( ) throw ; // cannot throw any e x c e p t i o n
v o i d f u n c 3 ( ) throw ( x ) ;
// throw x e x c e p t i o n and e x c e p t i o n d e r i v e d from x

10.8.1 Dynamic Exception Specification (Deprecated)

Dynamic exception specifications use the throw() specifier to indicate the types of
exceptions that a function may throw. This is deprecated in modern C++ in favor
of noexcept.

Syntax:

r e t u r n t y p e f u n c t i o n n a m e ( p a r a m e t e r l i s t ) throw ( e x c e p t i o n l i s t ) ;

In this syntax:

• return type is the return type of the function.

• function name is the name of the function.

© iamsspoudel
21

• parameter list is the list of parameters the function takes.

• exception list is a comma-separated list of exception types that the function


may throw.

Example:

v o i d p r o c e s s F i l e ( c o n s t s t d : : s t r i n g& f i l e n a m e )
throw ( r u n t i m e e r r o r )
{
// Code t h a t may throw s t d : : r u n t i m e e r r o r
}

10.8.2 Noexcept Specification

noexcept is a specifier used to declare that a function does not throw any exceptions.
This provides information to the compiler and allows for optimizations. If a function
does throw exceptions, it is best practice to specify which exceptions it may throw
using noexcept(false).

Syntax:

return type function name ( p a r a m e t e r l i s t ) noexcept ;

Example:

v o i d p r o c e s s F i l e ( c o n s t s t d : : s t r i n g& f i l e n a m e ) n o e x c e p t {
// Code t h a t does not throw e x c e p t i o n s
}

Example:

#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
#i n c l u d e <s t r i n g >

u s i n g namespace s t d ;

// Function t o p r o c e s s a f i l e , may throw r u n t i m e e r r o r


v o i d p r o c e s s F i l e ( c o n s t s t r i n g& f i l e n a m e ) n o e x c e p t ( f a l s e ) {

© iamsspoudel
22

// S i m u l a t e an e r r o r c o n d i t i o n f o r d e m o n s t r a t i o n
bool errorCondition = true ;
// Replace with a c t u a l e r r o r −c h e c k i n g l o g i c

i f ( errorCondition ) {
throw r u n t i m e e r r o r ( ” F a i l e d t o p r o c e s s f i l e : ” + f i l e n a m e ) ;
}

// P r o c e s s t h e f i l e i f no e r r o r
cout << ” P r o c e s s i n g f i l e : ” << f i l e n a m e << e n d l ;
}

i n t main ( ) {
s t r i n g f i l e n a m e = ” example . t x t ” ;

try {
processFile ( filename ) ;
} c a t c h ( c o n s t r u n t i m e e r r o r& e ) {
c e r r << ” E r r o r : ” << e . what ( ) << e n d l ;
r e t u r n 1 ; // Return non−z e r o t o i n d i c a t e e r r o r
}

return 0;
}

It’s important to note that dynamic exception specifications are deprecated in


modern C++, and noexcept is preferred. Additionally, specifying noexcept(false) is
optional, as it is the default behavior for functions that may throw exceptions.

10.9 Handling Uncaught and Unexpected Exceptions

Handling uncaught and unexpected exceptions in C++ is crucial for ensuring robust-
ness and reliability in your programs. Uncaught exceptions occur when an exception
is thrown but not caught by any try-catch block, leading to program termination. Un-

© iamsspoudel
23

expected exceptions refer to exceptions that are thrown in situations not accounted
for in the code. Handling these scenarios gracefully can help prevent abrupt pro-
gram termination and improve user experience. Here’s how to handle uncaught and
unexpected exceptions:

10.9.1 Uncaught Exceptions

To handle uncaught exceptions, you can set up a global exception handler using
std::set terminate() or std::set unexpected(). These functions allow you to specify
custom handlers to be invoked when an uncaught exception occurs.

Syntax:

#i n c l u d e <i o s t r e a m >
#i n c l u d e <e x c e p t i o n >
#i n c l u d e <c s t d l i b > // f o r a b o r t
u s i n g namespace s t d ;
v o i d myTerminate ( ) {
c o u t << ”Custom t e r m i n a t e h a n d l e r c a l l e d ” << e n d l ;
a b o r t ( ) ; // o r any o t h e r t e r m i n a t i o n f u n c t i o n you p r e f e r
}

v o i d someFunction ( ) {
throw r u n t i m e e r r o r ( ” Oops ! Something went wrong . ” ) ;
}

i n t main ( ) {
s e t t e r m i n a t e ( myTerminate ) ; // Se t custom t e r m i n a t e h a n d l e r
try {
someFunction ( ) ;
} c a t c h ( c o n s t e x c e p t i o n& e ) {
c e r r << ” E xce pt ion caught : ” << e . what ( ) << e n d l ;
}

return 0;

© iamsspoudel
24

10.9.2 Unexpected Exceptions

Unexpected exceptions can be handled using std::unexpected() function. You can set
up a custom unexpected handler using std::set unexpected() to specify the behavior
when an unexpected exception occurs.

Syntax:

#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t d e x c e p t >
u s i n g namespace s t d ;
void dangerousFunction ( ) {
throw r u n t i m e e r r o r ( ” Dangerous f u n c t i o n e n c o u n t e r e d an e r r o r ! ” ) ;
}

i n t main ( ) {
try {
dangerousFunction ( ) ;
} c a t c h ( c o n s t e x c e p t i o n& e ) {
c e r r << ” Caught e x c e p t i o n : ” << e . what ( ) << e n d l ;
} catch ( . . . ) {
c e r r << ” Caught unexpected e x c e p t i o n ! ” << e n d l ;
}

cout << ” Continuing program a f t e r c a t c h i n g e x c e p t i o n s . ” << e n d l ;

return 0;
}

Example:

Here’s an example demonstrating how to set up custom handlers for uncaught and
unexpected exceptions:

#i n c l u d e <i o s t r e a m >

© iamsspoudel
25

#i n c l u d e <e x c e p t i o n >
u s i n g namespace s t d ;

v o i d customTerminateHandler ( ) {
c e r r <<”Uncaught e x c e p t i o n d e t e c t e d . Terminating program.”<< e n d l ;
abort ( ) ; // Terminate program f o r c e f u l l y
}

v o i d customUnexpectedHandler ( ) {
c e r r <<”Unexpected e x c e p t i o n d e t e c t e d . Terminating program.”<< e n d l ;
a b o r t ( ) ; // Terminate program f o r c e f u l l y
}

i n t main ( ) {
s e t t e r m i n a t e ( customTerminateHandler ) ;
s e t u n e x p e c t e d ( customUnexpectedHandler ) ;

try {
// Main program l o g i c
throw r u n t i m e e r r o r ( ” Unexpected e r r o r o c c u r r e d ” ) ;
} c a t c h ( c o n s t e x c e p t i o n& e ) {
c e r r << ” Caught e x c e p t i o n : ” << e . what ( )
<< e n d l ;
}

return 0;
}

In this example:

• customTerminateHandler() and customUnexpectedHandler() are custom termi-


nation and unexpected handlers, respectively.

• They are set using std::set terminate() and std::set unexpected() before the
main() function.

© iamsspoudel
26

• If an uncaught or unexpected exception occurs during program execution, the


respective handler functions will be called, providing a chance to log the error
and perform cleanup operations before terminating the program.

Some Important Questions


1. Explain about all exception handling constructs.(3)

2. What are the advantages of exception handling over conventional error han-
dling? How is multiple exception handling performed in C++ with suitable
example? (3+5)

3. Explain Uncaught and Unexpected Exceptions handling. (3)

© iamsspoudel

You might also like