Broad Network


Basics of Exceptions in C++

Exception Handling in C++ - Part 1

Forward: In this part of the series we look at the basics of exception in C++.

By: Chrysanthus Date Published: 24 Aug 2012

Basics of Exceptions in C++

This is part 1 of my series, Exception Handling in C++. In this part of the series we look at the basics of exception in C++. You need basic knowledge in C++ and C++ Object Oriented Programming in order to understand this series. If you do not have knowledge in any of those fields, then from this blog, read the series whose first part is titled, “Getting Started with C++” and another whose first part is titled “OOP Basics in C++”. To reach any of the series, just type the title and my name Chrys in the Search Box of this page and click Search.

Note: If you cannot see the code or if you think anything is missing (broken link, image absent), just contact me at forchatrans@yahoo.com. That is, contact me for the slightest problem you have about what you are reading.

Runtime Error Example
Consider the following code:

#include <iostream>
using namespace std;

int main()
    {
        int numerator = 8;
        int denominator = 2;

        if (denominator != 0 )
            {
                int answer = numerator/denominator;
                cout << answer;
            }
        else
            {
                cout << "Division by zero is not allowed!";
            }
    
        return 0;
    }

This code basically divides two numbers. In life you cannot divide a number by zero. Assuming that the denominator is input by the user, he may input zero. The division (process) by zero should not be allowed.

Let us look at what is in the code: the first two statements in the main function block are initialization of integers. The division should take place in the if-block. The if-condition checks whether the denominator is zero. If it is not, the division takes place in the if-block. If it is, the else part of the if-construct displays an error message to the user. This code segment is OK, because if the denominator is zero, the if-block will not be executed and no division will take place. With the above code, the execution of the program continues after the if/else construct.

This if/else construct does the division and prevents runtime error from taking place. The if-block does the division; the if-condition checks if error would occur; if error would occur, the else block display an alert message and the if-block and division are not executed.

Basic Components of Exception
With exception handling, you have what is called the try/catch construct. The try block has an important expression, which is, throw. throw takes an argument (operand).

In the above if/else construct, the code segment of interest, which is the segment required, is the if-block. This if-block is what does the division. With Exception handling that code segment of interest goes into the try-block; the error message code segment or error handler code segment goes into the catch-block. The throw expression in the try-block calls the catch-block passing its argument to it. The catch construct is like a function. This is the basic syntax for exception handling,

    try
        {
            //statements of interest
            throw identT;
        }
    catch (int identC)
        {
            //handle the error
        }

The argument for the throw expression does not go into parentheses. The catch-construct has a parameter. The argument for the throw expression must be of the same type as the parameter of the catch construct. You are the one who decides on the object type of the parameter, which is the same as the object type of the argument. The argument of the throw expression can be a literal or an identifier. You are the one who decides on that. You take these decisions depending on the nature of the error and how you want to handle the error.

The catch-block should immediately follow the try-block in your typing, as in the above syntax.

The previous code is re-written using the try/catch construct as follows:

#include <iostream>
using namespace std;

int main()
    {
        int numerator = 8;
        int denominator = 2;

        try
            {
                if (denominator != 0 )
                    {
                        int answer = numerator/denominator;
                        cout << answer;
                    }
                else
                    {
                        throw 0;
                    }
            }
        catch (int e)
            {
                if (e == 0)
                    cout << "Division by zero is not allowed!";
            }
    
        return 0;
    }

Read through the above code, if you have not already done so. In many cases, the try-block equivalently has an if-condition whose block will execute if the condition does not detect the error. If the condition detects the error, the if-block will not execute, and the else part will throw the exception; that is the else part will call the catch-block sending the argument of the throw expression to it. The catch block uses the argument to display an appropriate error message to the user. This is what happens in many cases. Errors are not usually handled in the real sense of the word; usually an error message is sent to the user, an if-construct in the try block prevents the error from actually occurring. After this execution, the program continues in sequence from the try/catch construct; and there is no termination of program even if an error was detected. Try the above code.

In the initialization of the denominator, above, replace the right operand with 0 and test the code again.

Now the try-block may actually have an if/else construct with many throws. The catch block may correspondingly have if/else constructs. You are the one who decides on which argument to give for a throw expression. In the catch block, the value of a particular argument can determine what you code as error message. Referring to the above code, one argument may be 0, another may be 5, another may be 10, and so on; you are the one to choose the values. Each throw normally takes one argument. If the arguments are of different object types, then you need one catch block for each type (see later).

Throw Expression in a Function
You can put what you need for the try block in a function as illustrated below:

#include <iostream>
using namespace std;

int numerator = 8;
int denominator = 0;

    void errFn()
        {
            if (denominator != 0 )
                {
                    int answer = numerator/denominator;
                    cout << answer;
                }
            else
                {
                    throw 0;
                }
        }

int main()
    {

        try
            {
                errFn();
            }
        catch (int e)
            {
                    cout << "Division by zero is not allowed!";
            }
    
        return 0;
    }

Note that in the catch block, this time, I have not used an if-statement. This is because, if the parameter of the catch construct is of the same type as the argument of the throw expression, then the catch-construct will catch the exception (will catch what has been thrown). Under this condition, it is not obligatory to use the identifier of the catch parameter in the catch-block.

Well, also note that the initialization of the numerator and denominator are now outside the main block (and the function block) and up in the code, so that they can be seen by any block in the code.

We have learned that the throw expression can be in the try block directly or in a function called by the try block. However, the catch block remains attached to the try block, whether or not the throw expression is in the try block directly or in function called by the try block.

Note: In practical programming, most catch blocks just send an error message to the user of the program; they do not really correct the error.

Let us take a break here and continue in the next part of the series.

Chrys

Related Links

C++ Taking the Bull by the Horns
C++ Just After the Basics
Object Oriented Programming in C++
C++ Operators
C++ Templates
Exception Handling in C++
Container Library Sequences in C++ Simplified
Associative Container in C++ Simplified
String in C++ Standard Library Simplified
Date and Time in C++ Simplified
Advanced Course
Storage Duration in C++
Scopes in C++
Function and Operator Overloading in C++
Specifiers in C++
Some Features of C++ Entities
C++ Preprocessing Directives
Writing a C++ Container
C++ Namespace
Writing a C++ Application
More Related Links
Relational Database and Sybase
Windows User Interface
Computer Programmer – A Jack of all Trade – Poem
C++ Course
NEXT

Comments

Become the Writer's Fan
Send the Writer a Message