---
title: "Slides for P3969R0 — Fixingstd::bit_castof types with padding bits"
document: P4038R0
date: 2026-03-10
audience: LEWG
reply-to:
  - "Jan Schultke < <janschultke@gmail.com>"
paper-type: proposal
---

# Fixing std::bit_cast of types with padding bits  P3969R0

Jan Schultke
 | 
Slides for P3969R0
—
Fixing

std::bit_cast

of types with padding bits
 | 
Telecons 2026
 | 
Slide 1

## The problem

//

GCC accepts (x == 0)

//

Clang rejects

constexpr

auto

x

=

std

::

bit_cast

<

__int128

>

(

0

.

0

L

)

;

- UB due to padding bits in 80-bit x87 `long double`
- this is (arguably) undiagnosed library UB
- `std::bit_cast<__int128, long double>` = `std::unreachable`
- it would be useful if it worked (for math function implementations)

Jan Schultke
 | 
Slides for P3969R0
—
Fixing

std::bit_cast

of types with padding bits
 | 
Telecons 2026
 | 
Slide 2

## The problem, cont.

struct

alignas

(

4

)

E

{

}

;

//

GCC and Clang error:

constexpr

auto

x

=

std

::

bit_cast

<

int

>

(

E

{

}

)

;

//

MSVC accepts:

static_assert

(

x

==

0

)

;

- MSVC treats padding in the original as zero
- see [https://developercommunity.visualstudio.com/t/11027496](https://developercommunity.visualstudio.com/t/11027496)
- maybe standardize the <del>bug</del> <ins>feature</ins>?

Jan Schultke
 | 
Slides for P3969R0
—
Fixing

std::bit_cast

of types with padding bits
 | 
Telecons 2026
 | 
Slide 3

## Possible solutions

"Mathematically correct" functions eliminate special cases and UB pitfalls:

| Single-function | Two-function |
| --- | --- |
| struct alignas(4) E { };
auto x = bit_cast<int>(E{});
assert(x == 0); // OK | struct alignas(4) E { };
auto x = bit_cast<int>(E{}); // error
auto y = bit_cast_zero_padding<int>(E{});
assert(x == 0); // OK |
| ✔️ already implemented (accidentally)

      ✔️ retroactively fixes code

      ✔️ safety by default

      ❌ doesn't express intent

      ❌ not really bit-casting

      ❌ hidden cost, no-opt out | ✔️ expresses intent

      ✔️ can opt out of cost

      ✔️ no semantic change between versions

      ❌ more complex

      ❌ unproven

      ❌ unimplemented |

Jan Schultke
 | 
Slides for P3969R0
—
Fixing

std::bit_cast

of types with padding bits
 | 
Telecons 2026
 | 
Slide 4

## Gotcha: clearing padding in unions

struct

alignas

(

4

)

E

{

}

;

union

U

{

int

x

;

E

e

;

}

;

auto

x

=

bit_cast_zero_padding

<

int

>

(

U

{

.

e

=

{

}

}

)

;

- `U` has padding only when `E` is active
- cannot clear padding without knowing active alternative
- this discussion is missing from the paper

Jan Schultke
 | 
Slides for P3969R0
—
Fixing

std::bit_cast

of types with padding bits
 | 
Telecons 2026
 | 
Slide 5

## References

[P3969R0]

Jan Schultke.

Fixing std::bit_cast of types with padding bits

2026-10-03

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3969r0.html
