C++ Logo

std-proposals

Advanced search

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

From: Jan Schultke <janschultke_at_[hidden]>
Date: Sat, 17 Jan 2026 20:17:04 +0100
> > I think giving people a compiler error is a sufficient fix for C++26.
>
> Well, I disagree, but I think we're coming to the point where we'll have
> to
> agree to disagree, and let the matter be resolved by the committee, with
> input
> from vendors and other user.s
>

Yeah, we'll see how LEWG feels about it.



> Making code that "works" today an error in C++26 via DR is going to be
> surprising.


Well no, that code does not work per se, or at least it's undefined
behavior and has a "works on my machine" effect.


> You may be right that it's always-UB to bit_cast to something
> other than a byte array, in which case it would be ok to turn this into an
> error. It would be beneficial to highlight where the UB was happening
> indeed.
>
> But that's not my preferred solution.
>
> I would especially advocate against making it a *compile* time error,
> because
> the code may have been constructed in such a way that it never gets
> executed
> (it was indeed unreachable). Making it a compile time error would turn
> perfectly well-defined-behaviour code into a hard error without a solution.
>

By the same logic, you could argue that an implicit conversion from std::map
to std::to_chars_result should compile because it's possible that the user
put it in an if (false) statement, so while it's complete nonsense, it may
not matter. It's widely understood that when the user does something that's
known to be a mistake at compile time, we don't tolerate it just because
execution may not reach the affected area.

If you can actually guarantee that the degenerate form of std::bit_cast you
have written is never executed, if constexpr or #if can eliminate it just
fine.

And leaving it as a *runtime* error wouldn't do much to help find where the
> problems lie.
>

Agreed. The issue is entirely detectable at compile time, so it should be
diagnosed at compile time. The only tool the standard has for this is
making the program ill-formed.


> > > Though that would introduce the question of "how do I know the compiler
> > > has
> > > the fixed behaviour?", which in turn begs the question for "what's the
> > > alternative?"
> >
> > You know the compiler has fixed behavior because you get an error.
>
> But it doesn't give me an alternative solution.
>
> If instead we do get the DR and if Arthur is correct that the DR will
> apply
> retroactively, then we get a solution in the much nearer future. It will
> apply
> to my code compiling as C++17 and may be something we can start to rely on
> around 2028, instead of being useful around the time 32-bit time_t
> overflows
> (2038).
>
> Though it's still true that if I *need* an alternative now, without a time
> machine I need to deploy it by myself, which I did with qHash(long
> double),
> which I will need to keep for the next couple of years / one decade
> anyway.
> But this is a very restricted solution because it only works because I
> *know*
> where the padding bits are. It is not generic.
>

I agree that it would be convenient to have a solution immediately, but the
overall design is always more important. In the overall design, if you
changed the existing bit_cast, you would add cost that is impossible to opt
out of, and you would break the intuition that bit_cast does not change any
bit values. It remains to be seen whether LEWG thinks those problems
outweigh the "we need a fix now!" factor.


> > Making std::bit_cast always wipe padding could violate user intent. After
> > all, the function is conceptually reinterpreting bits as is, and a change
> > in their value may be an extreme surprise. This really shouldn't happen
> > without you expressing that you know it's happening and that you want
> that
> > behavior.
>
> Indeed, and it's a drawback of my proposal.
>
> But my counter-argument, weak though it may be, is that no one could have
> meant to use those indeterminate-state bits. Copying them unmodified
> serves
> little purpose.
>

Leaving them indeterminate leaves the user the freedom to overwrite them,
ignore them, or to propagate them in their indeterminate state. Having
those options without any forced added cost is clearly useful.

Received on 2026-01-17 19:17:19