#2std::bit_cast

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 and To must be both trivially copyable,
  • To must be the same size as From,
  • 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.

Sample code

References

  1. What is the Strict Aliasing Rule and Why Do We Care?
  2. Type punning in modern C++ - Timur Doumler - CppCon 2019
  3. std::bit_cast on cppreference.com
  4. p0476r2 Bit-casting object representations proposal

All (4 shorts)