Bit-precise integers β€” _BitInt in C++

Document number:
P3666
Date:
2025-07-03
Audience:
SG6, SG22, EWG
Project:
ISO/IEC 14882 Programming Languages β€” C++, ISO/IEC JTC1/SC22/WG21
Reply-to:
Jan Schultke <janschultke@gmail.com>
GitHub Issue:
wg21.link/P3666/github
Source:
github.com/Eisenwave/cpp-proposals/blob/master/src/bitint.cow

C23 has introduced so-called "bit-precise integers" into the language, which should be brought to C++ for compatibility, among other reasons. Following an exploration of possible designs in [P3639R0] "The _BitInt Debate", this proposal introduces a new set of fundamental types to C++.

Contents

1

Introduction

2

Design discussion

2.1

Why not make it a library type?

2.1.1

Full C compatibility requires fundamental types

2.1.2

Quality of implementation requires a fundamental type

3

Impact on implementations

4

Impact on the standard

5

Proposed wording

6

References

1. Introduction

[N2763] introduced the _BitInt set of types to the C23 standard, and [N2775] further enhanced this feature with literal suffixes. For example, this feature may be used as follows:

// 8-bit unsigned integer initialized with value 255. // The literal suffix wb is unnecessary in this case. unsigned _BitInt(8) x = 0xFFwb;

In short, the behavior of these bit-precise integers is as follows:

2. Design discussion

2.1. Why not make it a library type?

[P3639R0] explored in detail whether to make it a fundamental type or a library type. Furthermore, feedback given by SG22 and EWG was to make it a fundamental type, not a library type. This boils down to two plausible designs (assuming _BitInt is already supported by the compiler), shown below.

𝔽 – Fundamental type 𝕃 – Library type
template <size_t N> using bit_int_t = _BitInt(N); template <size_t N> using bit_uint_t = unsigned _BitInt(N); template <size_t N> class bit_int { private: _BitInt(N) _M_value; public: // ... }; template <size_t N> class bit_uint { /* ... */; };

The reasons why we should prefer the left side are described in the following subsections.

2.1.1. Full C compatibility requires fundamental types

_BitInt in C can be used as the type of a bit-field, among other places:

struct S { _BitInt(32) x : 10; };

Since C++ does not support the use of class types in bit-fields, such a struct S could not be passed from C++ to a C API.

Furthermore, expressions of type _BitInt can be used as array sizes, in case labels, and any other place where integers but not class types are permitted. A developer would face severe difficulties when porting C code which makes use of these capabilities to C++.

2.1.2. Quality of implementation requires a fundamental type

While a library type class bit_int gives the implementation the option to provide no builtin support for bit-precise integers, to achieve high-quality codegen, a fundamental type is inevitably needed anyway. If so, class bit_int is arguably adding pointless bloat.

For example, when an integer division has a constant divisor, like x / 10, it can be optimized to a fixed-point multiplication, which is much cheaper. Performing such an optimization requires the compiler to be aware that a division is taking place, and this fact is lost when division is implemented in software, as a loop which expands to hundreds of IR instructions.

"Frontend awareness" of these operations is also necessary to provide compiler warnings when a division by zero or a bit-shift with undefined behavior is spotted. Use of pre on e.g. bit_int::operator/ cannot be used to achieve this because numerics code needs to have no hardened preconditions and no contracts, for performance reasons. Another workaround would be an ever-growing set of implementation-specific attributes, but at that point, we may as well make it fundamental.

3. Impact on implementations

4. Impact on the standard

5. Proposed wording

6. References

[N5008] Thomas KΓΆppe. Working Draft, Programming Languages β€” C++ 2025-03-15 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/n5008.pdf
[N2763] Aaron Ballman, Melanie Blower, Tommy Hoffner, Erich Keane. Adding a Fundamental Type for N-bit integers 2021-06-21 https://open-std.org/JTC1/SC22/WG14/www/docs/n2763.pdf
[N2775] Aaron Ballman, Melanie Blower. Literal suffixes for bit-precise integers 2021-07-13 https://open-std.org/JTC1/SC22/WG14/www/docs/n2775.pdf