MSDN Community

Structured Exception Handling (SEH) in Win32

Posted by JohnDoe on Sep 18, 2025

I'm trying to understand how Structured Exception Handling works in native Win32 applications. Specifically, I want to know:

  1. How does the compiler generate the exception handling tables?
  2. What are the differences between __try/__except and C++ exceptions?
  3. Can SEH be used from a pure C program?

Any examples or deep dives would be appreciated.

#include <windows.h>
int main() {
    __try {
        int *p = NULL;
        *p = 42; // Access violation
    } __except(EXCEPTION_EXECUTE_HANDLER) {
        printf("Caught exception!\\n");
    }
    return 0;
}
Answer by JaneSmith on Sep 18, 2025

Great question! Here's a concise breakdown:

  • Exception tables: The Visual C++ compiler emits a .pdata section containing unwind information. The linker combines these sections, and the OS loader reads them to build a table used by RtlLookupFunctionEntry.
  • __try/__except vs C++ exceptions:
    • SEH works at the OS level, handling hardware exceptions (e.g., access violations) and software exceptions raised via RaiseException.
    • C++ exceptions are a language feature that ultimately use SEH under the hood on Windows, but they are limited to C++ objects and have different semantics (e.g., stack unwinding via destructor calls).
  • Using SEH in C: Yes, you can use the Microsoft-specific extensions (__try/__except) in plain C. Just include windows.h and compile with /TC (C mode).

Below is a more elaborate example that demonstrates filtering based on exception code:

#include <windows.h>
#include <stdio.h>

int main(void) {
    __try {
        int *p = NULL;
        *p = 123; // triggers EXCEPTION_ACCESS_VIOLATION
    } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        printf("Access violation caught!\\n");
    }
    return 0;
}
Answer by MikeLee on Sep 19, 2025

Another thing to note is that SEH can be disabled in newer Windows versions for security reasons (e.g., SetUnhandledExceptionFilter changes). If you need reliable exception handling across platforms, consider using C++ try/catch or structured error handling via return codes.