Date: Sat, 17 Jan 2026 10:43:28 -0800
On Saturday, 17 January 2026 08:21:53 Pacific Standard Time Jan Schultke wrote:
> > > It would only require adding #if for a few versions, just like any other
> > > feature. One should always prioritize the overall design, which lives
> > > for
> > > decades rather than the temporary transition state.
> >
> > But reality says that those codebases linger for a ong time. Yes, it's a
> > transition, but I wouldn't expect a C++29 #if to disappear before 2039.
> >
> > I would prefer to see the behaviour fixed in the 2026 compilers.
>
> 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
Making code that "works" today an error in C++26 via DR is going to be
surprising. 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.
And leaving it as a *runtime* error wouldn't do much to help find where the
problems lie.
> > 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.
> Well, I think that the proposal creates the ideal workflow here. If you run
> into the degenerate form, you get an error. At that point, you either
>
> - realize that bit-casting between your types cannot possibly work due
> to padding issues, and you do something else, or
> - opt into the solution presented by std::bit_cast_zero_padding,
> expressing your intent clearly.
I understand your position, but I disagree.
> 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.
> Yeah, and this is the common case, and std::bit_cast works fine for that
> common case.
Agreed it's the common case.
But it's not the *generic* case.
> > > It would only require adding #if for a few versions, just like any other
> > > feature. One should always prioritize the overall design, which lives
> > > for
> > > decades rather than the temporary transition state.
> >
> > But reality says that those codebases linger for a ong time. Yes, it's a
> > transition, but I wouldn't expect a C++29 #if to disappear before 2039.
> >
> > I would prefer to see the behaviour fixed in the 2026 compilers.
>
> 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
Making code that "works" today an error in C++26 via DR is going to be
surprising. 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.
And leaving it as a *runtime* error wouldn't do much to help find where the
problems lie.
> > 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.
> Well, I think that the proposal creates the ideal workflow here. If you run
> into the degenerate form, you get an error. At that point, you either
>
> - realize that bit-casting between your types cannot possibly work due
> to padding issues, and you do something else, or
> - opt into the solution presented by std::bit_cast_zero_padding,
> expressing your intent clearly.
I understand your position, but I disagree.
> 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.
> Yeah, and this is the common case, and std::bit_cast works fine for that
> common case.
Agreed it's the common case.
But it's not the *generic* case.
-- Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org Principal Engineer - Intel Data Center - Platform & Sys. Eng.
Received on 2026-01-17 18:43:39
