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
Contents
Introduction
Design discussion
Why not make it a library type?
Full C compatibility requires fundamental types
Quality of implementation requires a fundamental type
Impact on implementations
Impact on the standard
Proposed wording
References
1. Introduction
[N2763] introduced the
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:
In short, the behavior of these bit-precise integers is as follows:
-
No integer promotion to
takes place.int - Mixed-signedness comparisons, implicit conversions, and other permissive feature are supported.
-
They have lower conversion rank than standard integers,
so an operation between
and_BitInt ( 8 )
yieldsint
, as does an operation withint
where_BitInt ( N )
is the width ofN
. They only have greater conversion rank when their width is greater.int
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
is already supported by the compiler), shown below.
π½ β Fundamental type | π β Library type |
---|---|
The reasons why we should prefer the left side are described in the following subsections.
2.1.1. Full C compatibility requires fundamental types
in C can be used as the type of a bit-field, among other places:
Since C++ does not support the use of class types in bit-fields,
such a
could not be passed from C++ to a C API.
Furthermore, expressions of type
can be used as array sizes,
in
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
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,
is arguably adding pointless bloat.
For example, when an integer division has a constant divisor, like
,
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
on e.g.
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.