Structured Exception Handling in Visual C++
An exception is an event that occurs during the execution of a program, and requires the execution of code outside the normal flow of control. There are two kinds of exceptions: hardware exceptions and software exceptions. Hardware exceptions are initiated by the CPU. They can result from the execution of certain instruction sequences, such as division by zero or an attempt to access an invalid memory address. Software exceptions are initiated explicitly by applications or the operating system. For example, the system can detect when an invalid parameter value is specified.
Exceptions like Access Violation, Divide by Zero are hardware exceptions. With /EHsc (default) or /EHs compiler options, C++ does not handle these hardware exceptions using standard C++ Exception Handling try and catch block. Below program would crash due to unhandled hardware exception, if /EHsc or /EHs compiler option is used.
There is an easy way to catch both standard C++ exceptions (software exceptions) and hardware exceptions using C++ Exception Handling try and catch block. Just enable /EHa compiler option in the project settings in Visual Studio (Project Properties -> C/C++ -> Code Generation -> Modify Enable C++ Exceptions to “Yes With SEH Exceptions (/EHa)”). Under this /EHa compiler option, below program would not crash as the exception will be caught.
Alternatively, both C and C++ programs can use the Structured Exception Handling (SEH) mechanism in the Windows operating system for handling both hardware and software exceptions identically. The concepts in SEH resemble the ones in C++ Exception Handling, except that SEH uses the __try, __except, and __finally constructs instead of try and catch.
Under the /EHa compiler option, if a hardware exception is raised in a C++ program, it can be handled by a structured exception handler with its associated filter or by a C++ catch handler, whichever is dynamically nearer to the exception context. For example, this sample C++ program raises a hardware exception inside a C++ try context:
Difference between Structured Exception Handling and Standard C++ Exception Handling:
The major difference between Structured Exception Handling (SEH) and Standard C++ Exception Handling is that the C++ exception handling model deals in types, while the C structured exception handling model deals with exceptions of one type; specifically, unsigned int. That is, C structured exceptions are identified by an unsigned integer value, whereas C++ exceptions are identified by data type.
A second difference is that the structured exception handling model is referred to as asynchronous, because exceptions occur secondary to the normal flow of control. The C++ exception handling mechanism is fully synchronous, which means that exceptions occur only when they are thrown.
- The /EHa compiler option supports handling of both standard C++ exceptions (software exceptions) and hardware exceptions by using the C++ try and catch clause. To implement SEH without specifying /EHa, you may use the __try, __except, and __finally syntax.
- Specifying /EHa and trying to handle all exceptions by using catch(…) can be dangerous. In most cases, asynchronous exceptions are unrecoverable and should be considered fatal. Catching them and proceeding can cause process corruption and lead to bugs that are hard to find and fix.
- When you use /EHsc or /EHs, the compiler assumes that exceptions can only occur at a throw statement or at a function call. This assumption allows the compiler to eliminate code for tracking the lifetime of many unwindable objects, which can significantly reduce code size. If you use /EHa, your executable image may be larger and slower, because the compiler doesn’t optimize try blocks as aggressively. It also leaves in exception filters that automatically clean up local objects, even if the compiler doesn’t see any code that can throw a C++ exception.
- Structured Exception Handling (SEH) is a Microsoft extension to C to handle certain exceptional code situations, such as hardware faults, gracefully. Although Windows and Microsoft Visual C++ support SEH, we strongly recommend that you use ISO-standard C++ exception handling (with /EHsc or /EHs). It makes your code more portable and flexible.