C++ Logo

std-proposals

Advanced search

[std-proposals] Fixing std::bit_cast padding bit issues

From: Jan Schultke <janschultke_at_[hidden]>
Date: Fri, 16 Jan 2026 08:50:24 +0100
Hi, there are two issues with std::bit_cast, and I'd like to open a
discussion for how to address these.

   1. There are forms of std::bit_cast that always have undefined behavior
   but are well-formed, making it equivalent to std::unreachable(). For
   example, given struct empty{} x, std::bit_cast<char8_t>(x) always has
   undefined behavior because the padding bits of empty would become
   indeterminate bits of char8_t. I'm not entirely sure how difficult it is
   to diagnose the condition for this, but it seems vaguely doable with
   reflection.
   2. It would be useful if you could obtain a result with padding bits
   turned into zero bits. For example, converting between integers and
   floating-point types is part and parcel of implementing numerical
   functions, but std::bit_cast<__int128>(0.0L) has undefined behavior
when long
   double is an 80-bit x87 floating-point type (which is padded to 16
   bytes). It seems implementable to have a form of std::bit_cast that
   converts padding bits in the source into zero bits in the destination.

These two issues are closely related. The padding-wipe behavior can be
added to std::bit_cast mostly without cost to existing code because the
padding-wipe only happens where currently, std::bit_cast maps padding bits
in the source onto non-padding bits in the destination. However, cost is
added when casting to e.g. an array of bytes; in that case, the bytes
become indeterminate and the behavior is well-defined.

This presents us with a few options:

   1. Make std::bit_cast ill-formed in the degenerate case, and possibly
   add another std::bit_cast_zero_padding function which wipes padding.
   2. Make std::bit_cast wipe padding, and possibly add another function
   with the current behavior so that you can cheaply cast to byte arrays.
   3. Keep the degenerate case as is, making std::bit_cast an alternative
   spelling of std::unreachable in some cases.

I think I prefer the second option, i.e. changing the behavior of
std::bit_cast to wipe padding, and adding another
std::bit_cast_indeterminate_padding function for the highly exotic case
where you bit-cast to byte arrays and cannot afford the cost of having some
of the bytes zeroed. This is spiritually similar to making variables
erroneous by default, and offering the [[indeterminate]] opt-out.

Received on 2026-01-16 07:50:37