Skip to content
Raymond Chen edited this page Apr 3, 2021 · 3 revisions

By default, WIL enables exception-based classes and helpers if C++ exceptions are enabled by one or more of the following compiler switches:

Disabling WIL exceptions

#define WIL_SUPPRESS_EXCEPTIONS

Define the WIL_SUPPRESS_EXCEPTIONS symbol before before including any WIL header files to disable the use of exceptions in WIL, even if exceptions would normally be enabled due to compiler switches.

WIL exception mode

The exception mode describes how you intend to combine files compiled with exceptions enabled and disabled.

The following exception modes are supported:

Exception mode Effect
#define WIL_EXCEPTION_MODE 0 Allow code compiled with exceptions enabled to be linked with code compiled with exceptions suppressed.
#define WIL_EXCEPTION_MODE 1 All code must be compiled with exceptions enabled.
#define WIL_EXCEPTION_MODE 2 All code must be compiled with exceptions suppressed.

All code must be compiled with the same exception mode. If you break this rule, you will get a linker error: ODR_violation_WIL_EXCEPTION_MODE_mismatch.

Mode 0 provides maximum flexibility, but it comes at a cost: WIL must erect extra exception barriers to prevent exceptions from escaping to non-exception code, and some function calls must be indirected through global pointers to avoid ODR violations. Setting up these global pointers at module load time will incur copy-on-write penalties.

Modes 1 and 2 result in more efficient code but require that all code that contributes to the module follow the same exception policy. Uses these modes where possible, preferably mode 1.

If you do not select an exception mode, WIL chooses one according to the following algorithm:

  • If WIL_LOCK_EXCEPTION_MODE is not defined, then use exception mode 0.
  • If WIL_LOCK_EXCEPTION_MODE is defined, then use exception mode 1 or 2, depending on whether exceptions are enabled.

For WIL implementors

To determine whether exceptions are enabled, check whether WIL_ENABLE_EXCEPTIONS is defined. You usually do this to remove classes and other helpers that use exceptions.

Example:

HRESULT get_thing_nothrow(Thing* result)
{
    ...
}

#ifdef WIL_ENABLE_EXCEPTIONS
Thing get_thing()
{
    Thing result;
    THROW_IF_FAILED(do_something_nothrow(&result));
    return result;
}
#endif