Before C++ 20, the most reliable method for type punning was using the std::memcpy
function. Other methods exist, but they often lead to undefined behavior due to restrictions that programmers can easily overlook.
For example, programmers typically use reinterpret_cast
to interpret a byte buffer as a struct
. Unfortunately, this leads to undefined behavior due to strict aliasing and object lifetime rules. Even though it often works as intended, the correct approach is to use std::memcpy
instead.
To improve the situation, C++ 20 introduced the std::bit_cast
function defined in the bit.h
header, which encapsulates the std::memcpy
pattern for reinterpreting one type as another.
The std::bit_cast
function accepts a reference to an object (referred to as From
) and returns another object (referred to as To
) of the type we want to reinterpret the input object as. There are a couple of restrictions imposed on From
and To
objects:
From
andTo
must be both trivially copyable,To
must be the same size asFrom
,To
must also be default constructible.
The std::bit_cast
template doesn't require additional language support, so programmers can implement their own versions if using a compiler that doesn't support C++ 20.