Date: Sat, 17 Jan 2026 08:13:29 -0800
On Saturday, 17 January 2026 07:58:47 Pacific Standard Time Jan Schultke wrote:
> > 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.
>
> Well yeah, the current design allows you to copy them around, and not much
> else. I don't see much motivation for changing that status quo though, and
> the problem described in the paper doesn't have to do with the case of
> casting to byte arrays.
But the paper needs to address the relevance to byte arrays.
> People diligently checking feature-test macros is a very optimistic
> assumption. The issue is that if we only change bit_cast, then the function
> compiles either way, whether it has UB or the compiler is recent and it's
> well-defined. If you're forced to spell it std::bit_cast_zero_padding, it
> either compiles and does the right thing, or it doesn't compile.
That is the argument you should spell out.
But stemming from the same optimistic assumption that people know what they're
doing, I come to a different conclusion: it's better to fix the behaviour of
what people already use than to require them to know they must use a different
tool.
We can also recommend that vendors backport the new behaviour to older
standards.
> 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.
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?"
> I don't think that std::bit_cast_zero_padding makes for a better "default"
> option anyway. std::bit_cast would be used in the vast majority of cases
> where you don't have padding issues, like casting float to int, or casting
> a type to a byte array.
>
> std::bit_cast_zero_padding solves a very specific edge case where you have
> padding bits in the source type and need to give them some arbitrary value
> in the destination type. I don't think this is common.
And I'm arguing that's the opposite: *knowing* there aren't padding bits is
the special case. In the general case, you don't. And in case of doubt, opt
for the safe alternative.
In the case where there aren't padding bits, the two functions have identical
behaviour after all.
And it's also quite surprising that a primitive type like long double can have
padding bits. No one realised that when we added qHash(long double) in 2014:
https://github.com/qt/qtbase/commit/c0791ac76ec7cfdc3945efa67a6f72ee3623413c
> > 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.
>
> Well yeah, the current design allows you to copy them around, and not much
> else. I don't see much motivation for changing that status quo though, and
> the problem described in the paper doesn't have to do with the case of
> casting to byte arrays.
But the paper needs to address the relevance to byte arrays.
> People diligently checking feature-test macros is a very optimistic
> assumption. The issue is that if we only change bit_cast, then the function
> compiles either way, whether it has UB or the compiler is recent and it's
> well-defined. If you're forced to spell it std::bit_cast_zero_padding, it
> either compiles and does the right thing, or it doesn't compile.
That is the argument you should spell out.
But stemming from the same optimistic assumption that people know what they're
doing, I come to a different conclusion: it's better to fix the behaviour of
what people already use than to require them to know they must use a different
tool.
We can also recommend that vendors backport the new behaviour to older
standards.
> 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.
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?"
> I don't think that std::bit_cast_zero_padding makes for a better "default"
> option anyway. std::bit_cast would be used in the vast majority of cases
> where you don't have padding issues, like casting float to int, or casting
> a type to a byte array.
>
> std::bit_cast_zero_padding solves a very specific edge case where you have
> padding bits in the source type and need to give them some arbitrary value
> in the destination type. I don't think this is common.
And I'm arguing that's the opposite: *knowing* there aren't padding bits is
the special case. In the general case, you don't. And in case of doubt, opt
for the safe alternative.
In the case where there aren't padding bits, the two functions have identical
behaviour after all.
And it's also quite surprising that a primitive type like long double can have
padding bits. No one realised that when we added qHash(long double) in 2014:
https://github.com/qt/qtbase/commit/c0791ac76ec7cfdc3945efa67a6f72ee3623413c
-- Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org Principal Engineer - Intel Data Center - Platform & Sys. Eng.
Received on 2026-01-17 16:13:37
