C++ Logo

std-proposals

Advanced search

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

From: Thiago Macieira <thiago_at_[hidden]>
Date: Sat, 17 Jan 2026 07:58:20 -0800
On Saturday, 17 January 2026 07:47:07 Pacific Standard Time Jan Schultke wrote:
> > I agree with not seeing the value of clear_padding. Even if there is a
> > path to
> > stably getting those bits cleared in order to make use of the non-padded
> > value, it's fragile. But more to the point: what's the purpose of having a
> > T
> > with its padding bits cleared? The intent of clearing those bits must be
> > that
> > one wants to observe them, and in T itself, they can't. Therefore, I argue
> > that the operation to clear the bits must transform the type into
> > something
> > else where the bits could be observed - that is a bit_cast operation.
>
> The purpose is to do type punning both at runtime and at compile-time, with
> the same code, in such a way that works if your type has padding bits too
> (e.g. long double). And yes, bit_cast is the right tool for that.

My paragraph was an argument against std::clear_padding and that the operation
to clear should also transform the type into a result where the cleared bits
could be observed.

Clearing but keeping in the same type where they definitely can't be observed
is pointless.

> > So should std::bit_cast() itself be amended to always clear the bits? When
> > would we not want that?
>
> That's certainly an option. I discuss that in
> https://isocpp.org/files/papers/D3969R0.html#why-not-make-std::bit_cast_zero
> _padding-the-default-behavior
>
> The issue is mainly that you get differences in behavior between compiler
> versions (or even standards, if this is not a DR). This would be a
> sharp edge. It also adds cost: an implementation of bit_cast is currently
> permitted to copy over the bits from the source in their original state.
> Clearing the bits would add cost to existing code. Without two separate
> functions, you have no way of opting out of the cost.

But what's the point of leaving those bits indeterminate, even in a byte
array? What can one do to them?

As in my reply as feedback: the compiler can avoid emitting the bit-clearing
code if it can tell you did not observe the cleared bits. For example:

uint64_t mantissa_of(long double ldbl)
{
    return std::bit_cast<unsigned __int128>(ldbl);
}

This returns the 64 bits of the mantissa of an 80-bit extended precision long
double, which never contain any padding, and therefore the compiler does not
need to clear the unobserved padding bits. And it can be written now, relying
on the compilers emitting suitable code even in spite of it being UB (as per
your intro, but see my feedback email).

But it only works if we fix std::bit_cast<unsigned __int128>.

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
  Principal Engineer - Intel Data Center - Platform & Sys. Eng.

Received on 2026-01-17 15:58:27