C++ Logo

std-proposals

Advanced search

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

From: Sebastian Wittmeier <wittmeier_at_[hidden]>
Date: Sat, 17 Jan 2026 17:37:45 +0100
You say the clearing version of bit_cast could change the value on a round-trip cast, if there is a type with padding bits as intermediate type?   Conceptually that should not work, as the type with padding has not enough bits for representation, but the one solution gives a compile error and the other just quietly clears bits and modifies the value.   -----Ursprüngliche Nachricht----- Von:Jan Schultke via Std-Proposals <std-proposals_at_[hidden]> Gesendet:Sa 17.01.2026 17:22 Betreff:Re: [std-proposals] Fixing std::bit_cast padding bit issues An:Thiago Macieira <thiago_at_[hidden]>; CC:Jan Schultke <janschultke_at_[hidden]>; std-proposals_at_[hidden];  > 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.  I think that a partial DR is exactly the right middle ground here. The addition of the Mandates clause to bit_cast could be treated as a DR, so that a compiler informs you you've run into the degenerate form regardless of version. The new function could be a DR, maybe not, I'm not sure.   > 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.   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.   > 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.  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. 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.   In the case where there aren't padding bits, the two functions have identical behaviour after all.  Yeah, and this is the common case, and std::bit_cast works fine for that common case.   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  Shit happens. -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2026-01-17 16:53:50