Exception Handling for C++
When exceptions occur, the programmer has to decide a strategy according to which he would handle the exceptions. The strategies could be, displaying the error messages on the screen, or displaying a dialog box in case of a GUI environment, or requesting the user to supply better or simply terminating the program execution.
When a function detects an exceptional situation, you represent this with an object. This object is called an exception object. In order to deal with the exceptional situation you throw the exception. This passes control, as well as the exception, to a designated block of code in a direct or indirect caller of the function that threw the exception. This block of code is called a handler. In a handler, you specify the types of exceptions that it may process and will pass control to the first appropriate handler that is able to process the exception thrown. When this happens, an exception is caught. A handler may rethrow an exception so it can be caught by another handler.
Usually C programmers deal with exceptions in two ways:
For example, if a recursive decent parser detects an error, it should report it and continue with further processing.
Let us look at these methods more closely.
In C programs a function usually returns an error value if an error occurs during execution of that function. For example, file-opening functions return a NULL indicating their inability to open a file successfully. Hence, each time we call these functions we can check for the return value. This is shown for some fictitious functions func1( ), func2( ) and func3( ) in the following code:
C does not provide an easy way to transfer control out of a function expect by returning to the expression that called the function. For the vast majority of function calls, this is a desirable limitation. You want the discipline of nested function calls and returns to help you understand the flow of control through a program. Nevertheless, on some occasions that discipline is too restrictive. The program is sometimes easier to write, and to understand, if you can jump out of one or more function invocations at a single stroke. You want to bypass the normal function returns and transfer control to somewhere in an earlier function invocation.
For example, you may want to return to execute some code for error recovery no matter where an error is detected in your application. The setjmp( ) and the longjmp( ) functions provide the tools to accomplish this. The setjmp( ) function saves the state or the context of the process and the longjmp( ) uses the saved context to revert to a previous point in the program. What is the context of the process? In general, the context of a process refers to information that enables you to reconstruct exactly the way the process was at a particular point in its flow of execution.
When setjmp( ) is called from main( ) it stores all the relevant information about the current processor state in jmp_buf and returns zero. In this case, the if statement is satisfied and the process( ) function is called.
If something goes wrong in process( ) (indicated by the flag variable), we call longjmp( ) with two arguments: the first is the buffer that contains the context to which we will return. When the stack reverts back to this saved state, and the return statement in longjmp( ) is executed, it will be as if we were returning from the call to setjmp( ), which originally saved the buffer buf. The second argument to longjmp( ) specifies the zero so that in the if statement we can tell whether the return is induced by a longjmp( ).
The setjmp( )/longjmp( ) combination enables us to jump unconditionally from one C function to another without using the conventional return statements. Essentially, setjmp( ) marks the destination of the jump and longjmp( ) is a non-local goto that executes the jump.
However, this approach is not appropriate for an object-oriented environment because it does not properly handle the destruction of objects. In our program when longjmp( ) returned the destructor of the sample class did not get called. Hence the object could not get properly cleaned up. This is the critical reason why a better alternative should be thought of for handling exceptions in C++.
C++ provides a systematic, object-oriented approach to handling run-time errors generated by C++ classes. The exception mechanism of C++ uses three new keywords: throw, catch, and try. Also, we need to create a new kind of entity called an exception class.
Suppose we have an application that works with objects of a certain class. If during the course of execution of a member function of this class an error occurs, then this member function informs the application that an error has occurred. This process of informing is called throwing an exception. In the application we have to create a separate section of code to tackle the error. This section of code is called an exception handler or a catch block. Any code in the application that uses objects of the class is enclosed in a try block. Errors generated in the try block are caught in the catch block. Code that doesn’t interact with the class need not be in a try blocks. It is not a working program, but it clearly shows how and where the various elements of the exception mechanism are placed.
throw errorclass( ) ;
When an exception is thrown control goes to the catch block that immediately follows the try block.
The following is one more example of a function try block with a member initializer, a function try block and a try block:
Exception thrown in f()
Exception thrown in g()
Exception thrown in A()
The constructor of class A has a function try block with a member initializer. Function f() has a function try block. The main() function contains a try block.
You can declare a handler to catch many types of exceptions. The allowable objects that a function can catch are declared in the parentheses following the catch keyword (the exception_declaration). You can catch objects of the fundamental types, base and derived class objects, references, and pointers to all of these types. You can also catch const and volatile types. The exception_declaration cannot be an incomplete type, or a reference or pointer to an incomplete type other than one of the following:
Re: Exception Handling for C++
i didnt knew about exception handling in c++
|All times are GMT +5.5. The time now is 19:24.|