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:46:30 -0800
On Saturday, 17 January 2026 03:22:24 Pacific Standard Time Jan Schultke via
Std-Proposals wrote:
> I've decided to tackle the issue in a proposal:
> https://isocpp.org/files/papers/D3969R0.html
>
> Thanks for the feedback, it's been quite helpful in making this draft and
> addressing possible design alternatives.

Feedback:

In the introduction:
Please introduce that you're talking about x86 and 80-bit extended-precision
long double before you talk about the bug. There are several architectures
where it isn't.

Is it UB to *cast* from long double to __int128? Or is it UB to observe the
padding bits on the destination?

Suppose for example one did:
  auto a = std::bit_cast<unsigned __int128>(0.0L);
  auto b = std::bit_cast<std::array<uint16_t, 8>>(a);

The value of the 128-bit integer was never observed, it was only used as a
source to casting to an array of 16 bytes. And observing the non-padding
bytes/words in that array shouldn't be UB, should it?

I wouldn't write "is an alternative spelling for std::unreachable". Please
elaborate on how you're reaching that conlusion: this operation is always UB
and therefore the compiler is allowed to assume didn't happen, therefore we
conclude that it is unreachable.

In the design:

I'm not satisfied with the arguments for leaving std::bit_cast unchanged for
byte arrays. What's the point of accessing the indeterminate padding bytes in
byte form? Since they are indeterminate, the program also has indeterminate
behaviour if one uses them in a control expression (I believe it turns UB
too). The only two things one *can* do to the indeterminate bytes are to copy
them to other bytes or to overwrite them with determinate bytes.

But then under as-if rule, the compiler can see whether one did any of that
and avoid emitting the pad-clearing.

As for using an older version of std::bit_cast, I don't see a problem. The
__cpp_lib_bit_cast macro would get updated to a new value, so application
developers would know the behaviour has been updated. If they would know to
use std::bit_cast_clear_padding(), they would also know to check the value of
the macro.

I would agree with the surprise that it does clear when one didn't expect it.
However, the end result is that std::bit_cast is relegated to the niche use-
cases and std::bit_cast_clear_padding is the general one, superior in almost
every aspect, and requires adding #if everywhere.

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

Received on 2026-01-17 15:46:45