Exception Handling 

An exception is an error that occurs at run time. Exceptions can be caused by external factors, such as insufficient resources, or internal factors such as an invalid pointer.C++’s exception-handling handles run-time errors in a structured and controlled manner. When an exception occurs a program can automatically invoke an error-handling routine to deal with the problem.

C++ exception handling is implemented using the three keywords: try, catch, and throw. Program statements can be monitored for exceptions in a try block. If an exception or error occurs within that try block, it is said to be 'thrown'. This thrown exception is caught by the appropriate catch statement, which then processes the exception. There can be more than one catch statement associated with any try. C++ provides a list of standard exceptions, in addition, the user can define their own exceptions by overriding exception class functionality. Exceptions can be generated anywhere within a code block using a throw statement.

In the sample code below the user is requested to enter an age value. Entering a value lower than 18 throws a “too young” exception. Entering a non-numeric value results in a “Not correct format” exception.

#include <iostream>
using namespace std;

int main()
{
int iAge;
cout << "Enter Age: ";
cin >> iAge;
try {
if (!cin)                
throw(!cin);         
if(iAge < 18)
throw(iAge);
cout << "\nCorrect Age: " << iAge << "\n\n";
}
catch(int age)
{
cout << "too young";
}
catch(...)
{
cout << "Not correct format \n";
}
cout << "\n";
return 0;
}

C++ Standard Exceptions

C++ provides a list of standard exceptions defined in the header file. A small sample of these is listed below

Exception   Description
std::exception   base class for exceptions thrown by the standard library components
std::bad_alloc   Thrown after a failure to allocate the requested storage space by the operator new.
std::bad_cast   The exception is thrown by dynamic_cast when it fails the run-time check
std::bad_exception   Handles unexpected exceptions in a C++ program
std::logic_error   reports errors that are a consequence of faulty logic within the program
std::length_error   Thrown when a std::string is to large when created
std::out_of_range   Reports errors that are a consequence of an attempt to access elements out of defined range.
std::overflow_error   Thrown in the event of a mathematical overflow
std::underflow_error   Thrown in the event of a mathematical underflow<

Creating a User-Defined exception class

A user-defined exception can be created by inheriting and overriding the base exception class found in the <exception> header. Using the std::exception class ensures that all existing exception handlers will automatically scale up to catch your new exception class as well because they share the same base class.

In the code sample below the user is asked to enter a positive integer value. The input is checked in the try block first for any values equal to and then lower than zero. Any unacceptable data will trigger an exception. what() is a public method provided by the exception class. It is used to return the cause of an exception.

#include <iostream>
#include <exception> 
using namespace std;
class checkValue : public exception {
public:
    int initialvalue = 0;

    const char* what() const throw () {
        cout << "Incorrect value";
    }
};
int main() {
    int initialValue = 0;
    cout << "Enter integer value greater than zero ";
    try {
        cin >> initialValue;
        cout << initialValue;
        if (initialValue == 0) throw checkValue();
        if (initialValue < 0) throw checkValue();
        cout << "your value is " << initialValue;
    }    catch (checkValue ex) {
        ex.what();
        cout << ex.initialvalue;
    }
    return 0;
}

Terminating program execution

exit()

Causes an immediate and orderly termination of a program without performing any regular cleanup tasks. It has the following prototype:

void exit(int status);

The value of status is returned as an exit code to the calling code. If this exit_code is 0 or EXIT_SUCCESS, a successful termination status is returned to the host environment. Any other value indicates that program termination is due to an error. The constant EXIT_FAILURE can also be used to indicate an unsuccessful termination.

In the code sample below an attempt is made to open a file. If that file does not exist the program execution is terminated

#include <stdio.h>      /* for printf, fopen */
#include <stdlib.h>     /* for exit, EXIT_FAILURE */
void test(){
 printf ("Error opening file");
    exit (EXIT_FAILURE);
)
int main ()
{
  FILE * pFileName;
  pFileName = fopen ("somefile.txt","r");
  if (pFileName ==NULL)
  {
   test();
  }
  else
  {
      printf ("File opened successfully:\n");
  }
  print ("the end");
  return 0;
}

quick_exit

Calls functions registered using at_quick_exit and then terminates the process normally by returning control to the host environment after calling all.

#include <stdio.h>      /* needed for printf */
#include <stdlib.h>     /*needed for at_quick_exit, quick_exit, EXIT_SUCCESS */
void fexit (void)
{
  printf ("Quick exit function.\n");
}
int main ()
{
    at_quick_exit (fexit);
    printf ("Start executions\n");
  quick_exit (EXIT_SUCCESS);
  printf ("Main function block");  // this is never executed
  return 0;
}
 

atexit

Automatically calls a function when a program terminates normally.

abort()

Causes immediate and abnormal program termination. It does not return any status information to the host environment, nor does it perform an orderly shutdown of your program.

assert()

Evaluates an Expression. If this expression evaluates to 0, this causes an assertion failure that terminates the program. It is normally used during debugging to capture programming errors and is disabled after the debugging phase.

#include <stdio.h>    
#include <assert.h>     /* assert */

void fnAssert(int value) {
     printf ("exiting\n");
  assert (value!=1);
 }
int main ()
{
    printf ("start \n");
    fnAssert(1);
    printf ("terminate");
    return 0;
}