Exceptions in C : __try vs. try/catch/finally
In C , the try/catch/finally constructs are used to handle exceptions. However, they can also be encountered with underscores, such as __try. This raises the question of when these underscores are necessary.
On Windows Platforms: Unifying Exception Handling
On Windows, exceptions are supported at the operating system level through Structured Exception Handling (SEH). They are comparable to Unix signals. Compilers targeting Windows leverage SEH to implement C exceptions.
Non-Standard __try and __except
To handle SEH exceptions in C , you must use the non-standard __try keyword instead of try. The __except keyword is similar to C 's catch, but it provides additional functionality. It allows you to specify an exception filter expression that determines whether an active exception should be caught.
__finally for Post-Exception Code Execution
The __finally keyword allows you to execute code after an exception has been handled. This feature is not present in standard C , but it is common in other languages.
Disabling Optimization for Destructor Invocation
The Microsoft compiler performs an optimization that can prevent destructors from being invoked in all cases during stack unwinding. If it determines that there is no throw within the scope that governs the object's lifetime, it skips the registration code. To ensure destructor invocation, use the /EHa compile option to suppress this optimization.
Example Demonstrating SEH and C Exception Handling
To illustrate the concepts, here's a code snippet that demonstrates how SEH exceptions allow for C destructor invocation and how C exceptions are built on top of SEH:
#include <iostream> class Example { public: ~Example() { std::cout << "destructed" << std::endl; } }; int filterException(int code, PEXCEPTION_POINTERS ex) { std::cout << "Filtering " << std::hex << code << std::endl; return EXCEPTION_EXECUTE_HANDLER; } void testProcessorFault() { Example e; int* p = 0; *p = 42; } void testCppException() { Example e; throw 42; } int main() { __try { testProcessorFault(); } __except(filterException(GetExceptionCode(), GetExceptionInformation())) { std::cout << "caught" << std::endl; } __try { testCppException(); } __except(filterException(GetExceptionCode(), GetExceptionInformation())) { std::cout << "caught" << std::endl; } return 0; }
Output:
Filtering c0000005 destructed caught Filtering e06d7363 destructed caught
This example showcases the handling of both SEH and C exceptions, demonstrating how destructors are invoked even during SEH exceptions.
The above is the detailed content of When Should You Use __try Instead of try/catch/finally in C ?. For more information, please follow other related articles on the PHP Chinese website!