This article is to explain in brief how Visual C++ is handling exceptions
Abnormal situations should be handled by throwing and catching exceptions. Such situations are not the same as normal error conditions, such as a function executing correctly, but returning a result code indicating an error. A normal error condition, for example, would be a file status function indicating that a file does not exist. For normal error conditions, the program should examine the error code and respond appropriately.
Visual C++ supports three kinds of exception handling:
• C++ exception handling
Although structured exception handling works with C and C++ source files, it is not specifically designed for C++. For C++ programs, you should use C++ exception handling.
• Structured exception handling
Windows supplies its own exception mechanism, called SEH. It is not recommended for C++ or MFC programming. Use SEH only in non-MFC C programs.
• MFC exceptions
MFC has used C++ exceptions but still supports its older exception handling macros, which are similar to C++ exceptions in form. The older MFC exception handling macros have been supported since version 1.0. Although these macros are not recommended for new programming, they are still supported for backward compatibility. In programs that already use the macros, you can freely use C++ exceptions as well.
Let us see all the three kinds in details
C++ exception handling
For this you can refer my article Exception Handling for C++.
Exception Handling for C++
Structured Exception Handling
Structured exception handling is a way to handle exceptions within a program. It is a mechanism for handling both hardware and software exceptions.
An exception is an event that occurs while the program is running. To prevent the program from crashing, the event may be captured, processed, reported, and hopefully handled properly so that the program can continue in a workable state. If exceptions are handled successfully, it allows for consistent reliable applications.
Windows 95, Windows 98, and Windows 2000 support handling exceptions, called structured exception handling, which involves cooperation of the operating system but also has direct support in the programming language.
An exception is an event that is unexpected or disrupts the ability of the process to proceed normally. This Exceptions can be detected by both hardware and software. Hardware exceptions include dividing by zero and overflow of a numeric type. Software exceptions include those you detect and signal to the system by calling the Raise Exception function and special situations detected by Windows.
One can write more reliable code with structured exception handling and also ensure that resources, such as memory blocks and files, are properly closed in the event of unexpected termination. You can also handle specific problems, such as insufficient memory, with concise structured code that does not rely on goto statements or elaborate testing of return codes.
There are two structured exception handling mechanisms:
• Exception handlers, which can respond to or dismiss the exception
Exception handlers are typically used to respond to specific errors. You can use the exception-handling syntax to filter out all exceptions other than those you know how to handle. Other exceptions should be passed to other handlers (possibly in the run-time library or the operating system) written to look for those specific exceptions.
Exception handlers use the try-except statement.
The following syntax describes a try-except statement:
The try-except statement is a Microsoft extension to the C and C++ languages that enables 32-bit target applications to gain control when events that normally terminate program execution occur. Such events are called exceptions, and the mechanism that deals with exceptions is called structured exception handling.
// guarded code
} __except ( expression )
// exception handler code
• Termination handlers, which are called when an exception causes termination inside a block of code.
Unlike an exception handler, a termination handler is always executed, regardless of whether the protected block of code terminated normally. The sole purpose of the termination handler should be to ensure that resources, such as memory, handles, and files, are properly closed regardless of how a section of code finishes executing.
Termination handlers use the try-finally statement.
The following syntax describes the try-finally statement:
The try-finally statement is a Microsoft extension to the C and C++ languages that enables 32-bit target applications to guarantee execution of cleanup code when execution of a block of code is interrupted. Cleanup consists of such tasks as deallocating memory, closing files, and releasing file handles. The try-finally statement is especially useful for routines that have several places where a check is made for an error that could cause premature return from the routine.
// guarded code
__finally ( expression )
// termination code
These two types of handlers are distinct, yet they are closely related through a process called "unwinding the stack." When an exception occurs, Windows looks for the most recently installed exception handler that is currently active.
The handler can do one of three things:
• Pass control to other handlers .
• Recognize but dismiss the exception.
• Recognize and handle the exception.
The exception handler that recognizes the exception may not be in the function that was running when the exception occurred. In some cases it may be in a function much higher on the stack. The currently running function, as well as all functions on the stack frame, are terminated. During this process, the stack is "unwound": local variables of terminated functions, unless they are static, are cleared from the stack.
As it unwinds the stack, the operating system calls any termination handlers you've written for each function. Use of a termination handler gives you a chance to clean up resources that otherwise would remain open due to abnormal termination. If you've entered a critical section, you can exit in the termination handler. If the program is going to shut down, you can perform other housekeeping tasks such as closing and removing temporary files.
Exception Handling in MFC
Two mechanisms are available in MFC exception-handling
• C++ exceptions, available in MFC version 3.0 and later:
MFC versions lower than 3.0 did not support the C++ exception mechanism. MFC provided macros to deal with exceptions. The macros are TRY, CATCH, and THROW. In contrast, the C++ exception keyword equivalents are try, catch, and throw. • MFC Exception Support
Here is a list of the MFC exception macros:
This macro throws the exception to the CATCH block. The program execution is interrupted. If a CATCH block is specified, program control goes to the CATCH block. If not, control is passed to an MFC library module to print an error message and exit.THROW_LAST
This macro throws a locally created exception. The macro sends the exception back to the next CATCH block. Usually when an exception that was just caught is thrown, it goes out of scope, thus being deleted. THROW_LAST passes the exception correct to the next CATCH handler.TRY
You use this macro to set up a TRY block, which signifies the block of code where the throwing of exceptions occurs. The exceptions are processed in the CATCH and AND_CATCH blocks. The TRY block is ended with an END_CATCH or END_CATCH_ALL macro.CATCH
This macro defines a block of code that catches the first exception thrown by a preceding TRY block. The TRY block should end with END_CATCH. AND_CATCH
You use this macro to catch additional exceptional types thrown from a preceding TRY block. Use the CATCH macro to catch the first exception type, and then use AND_CATCH for every other exception type. The TRY block should end with END_CATCH. AND_CATCH_ALL
This macro catches additional exception types thrown by a preceding TRY block. Use the CATCH macro to catch the first exception type, and then use AND_CATCH_ALL for all other exception types. The TRY block should end with END_CATCH_ALL. END_CATCH
This macro signifies the end of the last CATCH or AND_CATCH block.END_CATCH_ALL
Signifies the end of the last CATCH_ALL or AND_CATCH_ALL block.Convert code using macros to use the C++ exception-handling keywords
1. Locate all occurrences of the MFC macros TRY, CATCH, AND_CATCH, END_CATCH, THROW, and THROW_LAST.
2. Replace or delete all occurrences of the following macros:
TRY (Replace it with try)
CATCH (Replace it with catch)
AND_CATCH (Replace it with catch)
END_CATCH (Delete it)
THROW (Replace it with throw)
THROW_LAST (Replace it with throw)
Whether you use the C++ exceptions directly or use the MFC exception macros, you will use CException or CException-derived objects that may be thrown by the framework or by your application.
The following shows the predefined exceptions provided by MFC.
CMemoryException for Out-of-memory
CFileException for File exception
CArchiveException for Archive/Serialization exception
CNotSupportedException for Response to request for unsupported service
CResourceException for Windows resource allocation exception
CDaoException for Database exceptions (DAO classes)
CDBException for Database exceptions (ODBC classes)
COleException for OLE exceptions
COleDispatchException for Dispatch (automation) exceptions
CUserException forException that alerts the user with a message box, then throws a generic CException