Document: P3969R0
Author: Jan Schultke
Date: 2026-02-20
Audience: LEWG
When you bit_cast a type with padding bits (like 80-bit long double) to a type without padding (like __int128), the padding bits map onto value bits in the destination. Those padding bits have indeterminate values. The result: std::bit_cast becomes an alternative spelling for std::unreachable(). The paper proposes either diagnosing this degenerate case or zero-filling padding bits.
This is the kind of sentence that makes you question every
bit_castyou've ever written. GCC acceptsbit_cast<__int128>(0.0L)and gives you 0. Clang rejects it. The standard says it's UB. Nobody agrees and the user loses.Just zero-fill the padding bits. It's what GCC already does. It's deterministic. It's portable. It works in constant expressions. The alternative - adding a new
bit_cast_zero_paddingfunction - is more ceremony for the same result. Change the existing behavior and be done with it.Zero-filling changes the observable behavior of
bit_castat runtime. Currently, padding bits are whatever the hardware left there - which meansbit_castcopies them faithfully. If we mandate zero-filling, the implementation must detect and zero padding bits at runtime. That's not free on all architectures.80-bit
long doubleon x87 has 6 bytes of padding in a 16-byte representation. This is the primary motivation. If you're implementing<cmath>and need to inspect the bit pattern of along double,bit_castto an integer type should just work. Currently it's UB and compilers disagree on what happens.The
_BitIntangle is important. If P3666R2 lands bit-precise integers, most_BitInttypes will have padding bits. The paper estimates 7/8 of all_BitIntwidths have padding. This degeneratebit_castbehavior would be a constant source of bugs.Jan Schultke wrote P3737R3 (
std::array), P3899R1 (floating-point overflow), and now this. Systematically finding and fixing spec corners. The committee needs more of this kind of work.