Quick quiz: What is the behavior of the following code:
Surprisingly, it depends! As I would expect, on many operating system / compiler combinations (such as
gcc version 3.4.4 20050721 (Red Hat 3.4.4-2) as tested by Keith Garner), the dereference of the null pointer leads to a segmentation fault. However, both Microsoft Visual Studio 6.0 and Visual Studio .NET 2003 print the message
Caught exception. and exit gracefully. Strange!
This behavior appears to be an unintended consequence of the way C++ exceptions were implemented by Microsoft. Seemingly, Visual C++ implements the C++ exception handling mechanism using Structured Exception Handling (SEH), and the null pointer dereference leads to a Structured Exception, most likely an
EXCEPTION_ACCESS_VIOLATION. (For a list of possible SEH codes, see the documentation for the
GetExceptionCode() function.) The
catch (...) statement ends up catching the Structured Exception, and the code proceeds accordingly.
This means that in Visual C++ 6.0 and Visual C++ .NET 2003,
catch (...) does not catch only exceptions thrown using the C++
throw keyword; rather, it may also catch any number of Structured Exceptions, including division by 0, stack overflow, data misalignment, etc. Fortunately, it seems that this behavior may be disabled with the
/EHs compiler option in Visual C++ .NET 2005.
However, until the day comes when all Windows code is compiled with Visual C++ .NET 2005 and the
/EHs option, I suggest avoiding the
catch (...) construct altogether. Personally, I’ve chosen to inherit my custom-defined exceptions from STL’s
std::exception and use
catch (const std::exception& ex) instead.