Date: Sat, 17 Jan 2026 21:03:13 +0100
On 17/01/2026 16:58, Thiago Macieira via Std-Proposals wrote:
> On Saturday, 17 January 2026 07:47:07 Pacific Standard Time Jan Schultke wrote:
>>> I agree with not seeing the value of clear_padding. Even if there is a
>>> path to
>>> stably getting those bits cleared in order to make use of the non-padded
>>> value, it's fragile. But more to the point: what's the purpose of having a
>>> T
>>> with its padding bits cleared? The intent of clearing those bits must be
>>> that
>>> one wants to observe them, and in T itself, they can't. Therefore, I argue
>>> that the operation to clear the bits must transform the type into
>>> something
>>> else where the bits could be observed - that is a bit_cast operation.
>>
>> The purpose is to do type punning both at runtime and at compile-time, with
>> the same code, in such a way that works if your type has padding bits too
>> (e.g. long double). And yes, bit_cast is the right tool for that.
>
> My paragraph was an argument against std::clear_padding and that the operation
> to clear should also transform the type into a result where the cleared bits
> could be observed.
>
> Clearing but keeping in the same type where they definitely can't be observed
> is pointless.
>
I agree that clearing padding that can't be observed would be pointless.
But the padding /can/ be observed - and not just via bit_cast. Every
object in C++ can be viewed as an array of unsigned char (or std::byte)
- by memcpy, or by casting a pointer to the object to a pointer to
unsigned char.
And there are plenty of situations where you would want the padding to
be seen as zeros, or at least to be consistent. Taking a hash of some
kind is the obvious case - whether it be for use in a hash-map
structure, for integrity checking (CRC, md5sum), or for secure hashing.
You might also want it to be zeroed out before passing the object
outside the program - storing it in a file, or transmitting it on a
network. Again, it is often helpful for data to be consistent, and more
paranoid people might want to avoid any risk of leakage of unintended
data. Often it is most efficient and convenient to access the data here
using std::byte or unsigned char pointers - and that means the padding
is visible.
I agree that having std::bit_cast<> zero out padding could often be
nice, and be a good way to get consistency between run-time and
compile-time evaluation. And it would be sufficient to get the kind of
zeroing semantics I suggested (though it might be difficult to implement
efficiently, avoiding extra copies of non-padding fields).
Converting a type into a similar type but with the padding bits and
bytes visible and zeroed out is, I think, an interesting idea - but I
fear it would be very difficult to specify accurately. This new type
could pick up the data fields of the original type, but what about its
methods, static data, other functions with overloads, its ancestors and
descendants, and anything else relevant to the type? I think all you
could reasonably do is convert to an array of unsigned char (or
std::byte) of appropriate size.
> On Saturday, 17 January 2026 07:47:07 Pacific Standard Time Jan Schultke wrote:
>>> I agree with not seeing the value of clear_padding. Even if there is a
>>> path to
>>> stably getting those bits cleared in order to make use of the non-padded
>>> value, it's fragile. But more to the point: what's the purpose of having a
>>> T
>>> with its padding bits cleared? The intent of clearing those bits must be
>>> that
>>> one wants to observe them, and in T itself, they can't. Therefore, I argue
>>> that the operation to clear the bits must transform the type into
>>> something
>>> else where the bits could be observed - that is a bit_cast operation.
>>
>> The purpose is to do type punning both at runtime and at compile-time, with
>> the same code, in such a way that works if your type has padding bits too
>> (e.g. long double). And yes, bit_cast is the right tool for that.
>
> My paragraph was an argument against std::clear_padding and that the operation
> to clear should also transform the type into a result where the cleared bits
> could be observed.
>
> Clearing but keeping in the same type where they definitely can't be observed
> is pointless.
>
I agree that clearing padding that can't be observed would be pointless.
But the padding /can/ be observed - and not just via bit_cast. Every
object in C++ can be viewed as an array of unsigned char (or std::byte)
- by memcpy, or by casting a pointer to the object to a pointer to
unsigned char.
And there are plenty of situations where you would want the padding to
be seen as zeros, or at least to be consistent. Taking a hash of some
kind is the obvious case - whether it be for use in a hash-map
structure, for integrity checking (CRC, md5sum), or for secure hashing.
You might also want it to be zeroed out before passing the object
outside the program - storing it in a file, or transmitting it on a
network. Again, it is often helpful for data to be consistent, and more
paranoid people might want to avoid any risk of leakage of unintended
data. Often it is most efficient and convenient to access the data here
using std::byte or unsigned char pointers - and that means the padding
is visible.
I agree that having std::bit_cast<> zero out padding could often be
nice, and be a good way to get consistency between run-time and
compile-time evaluation. And it would be sufficient to get the kind of
zeroing semantics I suggested (though it might be difficult to implement
efficiently, avoiding extra copies of non-padding fields).
Converting a type into a similar type but with the padding bits and
bytes visible and zeroed out is, I think, an interesting idea - but I
fear it would be very difficult to specify accurately. This new type
could pick up the data fields of the original type, but what about its
methods, static data, other functions with overloads, its ancestors and
descendants, and anything else relevant to the type? I think all you
could reasonably do is convert to an array of unsigned char (or
std::byte) of appropriate size.
Received on 2026-01-17 20:03:18
