Date: Sun, 18 Jan 2026 12:45:22 +0300
On January 16, 2026 8:06:57 PM Thiago Macieira via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> On Friday, 16 January 2026 08:42:31 Pacific Standard Time Andrey Semashev via
> Std-Proposals wrote:
>> If you're referring to my definition of clear_padding then this is not
>> how I defined it, precisely because of this. My definition was:
>>
>> template< typename T >
>> void clear_padding(T& val) noexcept;
>>
>> i.e. the function would operate on the existing object in-place. Then,
>> that same object is passed to bit_cast by reference.
>
> I still think that's too fragile, because the reloading of val from where it
> was stored in memory may reintroduce indeterminate padding bits.
>
> From the abstract machine's perspective, the padding bits may suddenly change
> out of thin air, without an operation in the memory location.
No, they can't. I don't see where the standard permits that. The only thing
that is permitted is to not preserving padding when the program copies
objects (which is expressed in value representation and doesn't include
padding).
If there are no other operations between clearing padding and consuming it
via memcpy, bit_cast or any other function that is specified to operate on
object representation (as opposed to value representation) or raw storage,
the compiler is not allowed to generate code that clobbers the padding.
> Concretely, imagine one has a wrapper function around std::bit_cast, in order
> to support pre-C++20 (not to mention that std::bit_cast itself is a function,
> not the intrinsic). Depending on the optimisation levels, the compiler may
> load and store the value one or more times from memory. And depending on how
> it chooses to do that, it may forego writing the padding bits to memory in one
> of the destinations.
A pre-C++20 function is probably using memcpy to emulate bit_cast and
memset or regular stores into an array of bytes to clear padding, none of
which is allowed to be optimized away or negated by optimizations.
<std-proposals_at_[hidden]> wrote:
> On Friday, 16 January 2026 08:42:31 Pacific Standard Time Andrey Semashev via
> Std-Proposals wrote:
>> If you're referring to my definition of clear_padding then this is not
>> how I defined it, precisely because of this. My definition was:
>>
>> template< typename T >
>> void clear_padding(T& val) noexcept;
>>
>> i.e. the function would operate on the existing object in-place. Then,
>> that same object is passed to bit_cast by reference.
>
> I still think that's too fragile, because the reloading of val from where it
> was stored in memory may reintroduce indeterminate padding bits.
>
> From the abstract machine's perspective, the padding bits may suddenly change
> out of thin air, without an operation in the memory location.
No, they can't. I don't see where the standard permits that. The only thing
that is permitted is to not preserving padding when the program copies
objects (which is expressed in value representation and doesn't include
padding).
If there are no other operations between clearing padding and consuming it
via memcpy, bit_cast or any other function that is specified to operate on
object representation (as opposed to value representation) or raw storage,
the compiler is not allowed to generate code that clobbers the padding.
> Concretely, imagine one has a wrapper function around std::bit_cast, in order
> to support pre-C++20 (not to mention that std::bit_cast itself is a function,
> not the intrinsic). Depending on the optimisation levels, the compiler may
> load and store the value one or more times from memory. And depending on how
> it chooses to do that, it may forego writing the padding bits to memory in one
> of the destinations.
A pre-C++20 function is probably using memcpy to emulate bit_cast and
memset or regular stores into an array of bytes to clear padding, none of
which is allowed to be optimized away or negated by optimizations.
Received on 2026-01-18 09:45:23
