Date: Fri, 16 Jan 2026 08:59:43 +0100
I am unsure, but another idea is if we could utilise reflection to create a
wrapper type to control padding as a fourth option, like:
std::bit_cast<foo>(pad_to_zero(bar)),
where pad_to_zero is something like:
template <typename T>
class pad_to_zero {
/*members of bar but with explicit padding set to zero/*
};
These would make the bit_cast with padding-to-zero explicit, we would not
need to change the bit cast implementation and there may be other places
where this could be useful.
Just my thoughts.
Best,
Robin
On Fri, Jan 16, 2026, 08:50 Jan Schultke via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> 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.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
wrapper type to control padding as a fourth option, like:
std::bit_cast<foo>(pad_to_zero(bar)),
where pad_to_zero is something like:
template <typename T>
class pad_to_zero {
/*members of bar but with explicit padding set to zero/*
};
These would make the bit_cast with padding-to-zero explicit, we would not
need to change the bit cast implementation and there may be other places
where this could be useful.
Just my thoughts.
Best,
Robin
On Fri, Jan 16, 2026, 08:50 Jan Schultke via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> 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.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2026-01-16 08:00:01
