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

The safe_cast template library in WIL is a set of template functions that provide a standard way to perform potentially unsafe integral casts. It should be used on narrowing casts, sign change casts, or casts that involve size_t or other types whose size varies based on target architecture.

Whether a cast is safe or potentially unsafe is determined at compile time through SFINAE:

  • If a cast is determined to be potentially unsafe, safe_cast wraps the appropriate integral cast defined in intsafe.h, checks the HRESULT, and handles the error case when the cast fails.
  • If a cast is known to always be safe, safe_cast will simply perform a static_cast.

There are three variants of safe_cast, differing on how they handle failures from intsafe. Which to use depends on your project's error handling model.

For implementation details, see safecast.h.

Usage

The safe_cast functions are defined in a header in WIL, to use in your project add the below includes to the source file or precompiled header.

#include <wil\safecast.h>

All functions are defined in the wil:: namespace.

Functions

Potentially-unsafe conversion Notes
t = safe_cast<T>(val); Throws if conversion fails. Requires exceptions enabled.
t = safe_cast_failfast<T>(val); Fails fast if conversion fails.
hr = safe_cast_nothrow<T>(val, &t); Returns HRESULT representing success/failure.
Always-safe conversion Notes
t = safe_cast<T>(val); Requires exceptions enabled.
t = safe_cast_failfast<T>(val);
t = safe_cast_nothrow<T>(val);

Note that for safe_cast_nothrow<T>, you must choose the appropriate overload depending on whether the conversion is potentially-unsafe or always-safe. You will get an error if you choose the wrong one.

In all cases, the reported error is the HRESULT from the intsafe conversion function.

Native wchar_t

The safe_cast operations also add support for handling native wchar_t conversions, which intsafe currently does not have. According to MSDN, in Windows when wchar_t is a native type, it has a value range that is the same as an unsigned short (0 to 65,535), therefore it can be treated as an unsigned short in the calls to intsafe. If the safe_cast is from a wchar_t, it is static_cast to an unsigned short in the call to intsafe. If the safe_cast is casting to a wchar_t, the result from intsafe is static_cast to a wchar_t before being returned by safe_cast.