r/wg21
P3969R0 - Fixing std::bit_cast of types with padding bits WG21
Posted by u/bit_cast_pedant · 5 hr. ago

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.

▲ 78 points (95% upvoted) · 7 comments
sorted by: best
u/unreachable_by_accident 64 points 4 hr. ago
A specialization std::bit_cast<To, From> is an alternative spelling for std::unreachable if From has padding bits and To does not

This is the kind of sentence that makes you question every bit_cast you've ever written. GCC accepts bit_cast<__int128>(0.0L) and gives you 0. Clang rejects it. The standard says it's UB. Nobody agrees and the user loses.

u/zero_fill_advocate 42 points 4 hr. ago

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_padding function - is more ceremony for the same result. Change the existing behavior and be done with it.

u/padding_bits_realist 19 points 3 hr. ago

Zero-filling changes the observable behavior of bit_cast at runtime. Currently, padding bits are whatever the hardware left there - which means bit_cast copies them faithfully. If we mandate zero-filling, the implementation must detect and zero padding bits at runtime. That's not free on all architectures.

u/long_double_sufferer 28 points 3 hr. ago

80-bit long double on 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 a long double, bit_cast to an integer type should just work. Currently it's UB and compilers disagree on what happens.

u/bitint_padding_watcher 14 points 2 hr. ago

The _BitInt angle is important. If P3666R2 lands bit-precise integers, most _BitInt types will have padding bits. The paper estimates 7/8 of all _BitInt widths have padding. This degenerate bit_cast behavior would be a constant source of bugs.

u/schultke_again 8 points 1 hr. ago

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.