Date: Sun, 23 Aug 2026 13:04:21 +0200
On Sun, 23 Aug 2026 at 12:23, Jāāā Gustedt <jens.gustedt_at_[hidden]> wrote:
> Jan,
>
> on Sun, 23 Aug 2026 07:25:26 +0200 you (Jan Schultke via Liaison
> <liaison_at_[hidden]>) wrote:
>
> > When working on a draft of P4444 std::big_int (
> > https://isocpp.org/files/papers/D4444R0.html#std::uint_multiprecision_t
> ),
> > we've stumbled upon the problem that C++ does not yet have a "word
> > type" that would be suitable as the "limb type" for multiprecision.
> > That is, the largest possible unsigned integer type that has native
> > arithmetic support.
>
> As Nevin mentionned the `intmax_t` trap, it would definitively be good
> to avoid yet another such ABI trap. So maybe leave such details opaque
> to the user and only export something like a
>
> ```
> struct {
> size_t len;
> /* maybe other members, e.g. sign */
> alignas(something) unsigned char[];
> };
> ```
>
> as a resizable storage container (with `realloc` or so) for these
> things.
>
It's an interesting idea, but I don't see it working out in the C++
standard library. Firstly, you can't truly leave the details opaque to the
user because if the alignment guarantees of the limb array is unknown, any
user code would involve some dead code that deals with weird sizes, even
though the byte array always has a size which is a multiple of, say, 8.
That constant needs to be exposed to make std::assume_aligned etc. usable
and thus avoid overhead. Even if you didn't expose that constant in the
standard, "clever" users would probably look into standard library
internals and write code that makes alignment assumptions without our
assistance.
And I would not want to throw type safety under the bus. Since you cannot
create something like a std::span<unsigned char alignas(8)> in C++,
nor an unsigned
char* alignas(8) in C, every function that passes around limb arrays comes
with preconditions that either add more UB to the language or require
pointless runtime checks. I would much rather be able to represent a limb
array using a type that carries all the necessary information.
Anyway, I can see how there is an ABI trap, but the most plausible solution
is to contain it to std::big_int. The currently proposed
std::uint_multiprecision_t would just be an alias for the limb type of
std::big_int, with no additional connotation beyond that. There are ways to
make the limb type more opaque, but they're kind of futile because it's not
like you can arbitrarily change the ABI of std::big_int just because you've
made the limb type opaque; it's still an ABI break.
> > For the most part, std::size_t coincidentally has the right size, but
> > e.g. on WASM32, std::size_t is 32-bit while there are i64 hardware
> > instructions for arithmetic. Every existing integer type (alias) has
> > the wrong size, either by design or due to historical reasons.
> >
> > I'm thus interested in standardizing a type alias in <stdint.h> that
> > has the size. In P4444, we call that uint_multiprecision_t, but
> > that's perhaps not universal enough. Names like "uint_maxfast_t" or
> > "uint_word_t" come to mind.
> >
> > What are your thoughts?
>
> I think that a bigint type would be good to have in C. But it should
> be an opaque library type, first, without extending C's arithmetic
> operators. If that works, we could integrate it more closely into the
> language, later.
>
To be clear, I'm not suggesting a big_int type for C, only the limb type
that could be used internally.
The C version of the feature would likely end up looking like a
stdc-prefixed version of GNU MP, and I'm not really sure how much benefit
there is to standardizing that, or whether WG14 has any appetite for
copying and pasting GMP into the C standard.
> > Also, since I'm not in the C committee
> > myself, is there anyone who is interested in championing a proposal
> > on the WG14 side?
>
> Unfortunately I would not have the bandwidth for this, sorry.
>
Unfortunate, but thanks for your feedback.
> Jan,
>
> on Sun, 23 Aug 2026 07:25:26 +0200 you (Jan Schultke via Liaison
> <liaison_at_[hidden]>) wrote:
>
> > When working on a draft of P4444 std::big_int (
> > https://isocpp.org/files/papers/D4444R0.html#std::uint_multiprecision_t
> ),
> > we've stumbled upon the problem that C++ does not yet have a "word
> > type" that would be suitable as the "limb type" for multiprecision.
> > That is, the largest possible unsigned integer type that has native
> > arithmetic support.
>
> As Nevin mentionned the `intmax_t` trap, it would definitively be good
> to avoid yet another such ABI trap. So maybe leave such details opaque
> to the user and only export something like a
>
> ```
> struct {
> size_t len;
> /* maybe other members, e.g. sign */
> alignas(something) unsigned char[];
> };
> ```
>
> as a resizable storage container (with `realloc` or so) for these
> things.
>
It's an interesting idea, but I don't see it working out in the C++
standard library. Firstly, you can't truly leave the details opaque to the
user because if the alignment guarantees of the limb array is unknown, any
user code would involve some dead code that deals with weird sizes, even
though the byte array always has a size which is a multiple of, say, 8.
That constant needs to be exposed to make std::assume_aligned etc. usable
and thus avoid overhead. Even if you didn't expose that constant in the
standard, "clever" users would probably look into standard library
internals and write code that makes alignment assumptions without our
assistance.
And I would not want to throw type safety under the bus. Since you cannot
create something like a std::span<unsigned char alignas(8)> in C++,
nor an unsigned
char* alignas(8) in C, every function that passes around limb arrays comes
with preconditions that either add more UB to the language or require
pointless runtime checks. I would much rather be able to represent a limb
array using a type that carries all the necessary information.
Anyway, I can see how there is an ABI trap, but the most plausible solution
is to contain it to std::big_int. The currently proposed
std::uint_multiprecision_t would just be an alias for the limb type of
std::big_int, with no additional connotation beyond that. There are ways to
make the limb type more opaque, but they're kind of futile because it's not
like you can arbitrarily change the ABI of std::big_int just because you've
made the limb type opaque; it's still an ABI break.
> > For the most part, std::size_t coincidentally has the right size, but
> > e.g. on WASM32, std::size_t is 32-bit while there are i64 hardware
> > instructions for arithmetic. Every existing integer type (alias) has
> > the wrong size, either by design or due to historical reasons.
> >
> > I'm thus interested in standardizing a type alias in <stdint.h> that
> > has the size. In P4444, we call that uint_multiprecision_t, but
> > that's perhaps not universal enough. Names like "uint_maxfast_t" or
> > "uint_word_t" come to mind.
> >
> > What are your thoughts?
>
> I think that a bigint type would be good to have in C. But it should
> be an opaque library type, first, without extending C's arithmetic
> operators. If that works, we could integrate it more closely into the
> language, later.
>
To be clear, I'm not suggesting a big_int type for C, only the limb type
that could be used internally.
The C version of the feature would likely end up looking like a
stdc-prefixed version of GNU MP, and I'm not really sure how much benefit
there is to standardizing that, or whether WG14 has any appetite for
copying and pasting GMP into the C standard.
> > Also, since I'm not in the C committee
> > myself, is there anyone who is interested in championing a proposal
> > on the WG14 side?
>
> Unfortunately I would not have the bandwidth for this, sorry.
>
Unfortunate, but thanks for your feedback.
Received on 2026-08-23 11:04:39
