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.

#include <iostream>
using namespace std;

void TestMethod()
{
int i = 0, j = 1;
j = j / i; // This will throw Divide by Zero exception
}

int main()
{
try
{
TestMethod();
}

// catch block will not be executed for /EHsc or /EHs
// catch block will be executed for /EHa
catch(...)
{
cout << "An exception was caught." << endl;
}
}

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.

// compile with: /EHsc, /EHs, or /EHa
#include <iostream>
#include <excpt.h>
using namespace std;

void TestMethod()
{
int i = 0, j = 1;
j = j / i; // This will throw Divide by Zero exception
}

int main()
{
__try
{
TestMethod();
}

// __except will catch the exception here.
__except(EXCEPTION_EXECUTE_HANDLER)
{
cout << "An exception was caught in __except." << endl;
}
}

Output:
An exception was caught in __except.

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:

// compile with: /EHa
#include <iostream>
using namespace std;
void SEHFunc()
{
__try
{
int x, y = 0;
x = 5 / y;
}
__finally
{
cout << "In finally." << endl;
}
}

int main()
{
try
{
SEHFunc();
}
catch(...)
{
cout << "An exception was caught in catch."<< endl;
}
}

Output:
In finally.
An exception was caught in catch.

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.

Summary:

  • 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.

C++ Programmer at Microsoft