C++ Logo

std-discussion

Advanced search

Re: Seeking clarification on make_signed/make_unsigned with character types

From: Jan Schultke <janschultke_at_[hidden]>
Date: Fri, 18 Sep 2026 19:06:32 +0200
It is worth mentioning that if P3666 is accepted, then _BitInt will not be
an eligible choice for make_signed<char16_t> or make_unsigned<char16_t>,
only standard or extended integer types.

See
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3666r4.html#meta.trans.sign

On Fri, 18 Sept 2026 at 16:08, Keenan Horrigan via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> Perhaps there's a more grounded example available using the _BitInt types,
> which Clang provides in C++ as extended integer types.
>
> The following code successfully compiles today on Clang:
>
> __extension__ using uint9_ext_t = unsigned _BitInt(9);
>
> static_assert(std::integral<uint9_ext_t>);
> static_assert(sizeof(uint9_ext_t) == 2);
> static_assert(std::numeric_limits<uint9_ext_t>::max() == 511);
>
> static_assert(std::integral<char16_t>);
> static_assert(sizeof(char16_t) == 2);
> static_assert(std::numeric_limits<char16_t>::max() == 65535);
>
> static_assert(std::same_as<std::make_unsigned_t<char16_t>, unsigned
> short>);
>
> Godbolt link: https://godbolt.org/z/8a5666rWd
>
> According to the 'make_unsigned' rules, 'make_unsigned<char16_t>' should
> be providing 'uint9_ext_t' here before it would provide the standard
> integer type 'unsigned short', right? But of course that would be
> undesirable because 'uint9_ext_t' is more narrow than 'char16_t', despite
> having the same size and the same sign.
>
> On Thursday, September 17th, 2026 at 1:56 AM, Keenan Horrigan <
> friedkeenan_at_[hidden]> wrote:
>
> > Hello,
> >
> > Recently I've been working on some code that needs to deal somewhat
> finely with integer/integral types, so I've been going and reading the
> standard to make sure that I'm staying within the bounds of the standard
> with regards to integer types. Something that caught my eye, and is
> somewhat meaningful to my code, is the specification of
> 'std::make_unsigned', which can be seen here:
> https://eel.is/c++draft/meta.trans.sign
> >
> > For signed and unsigned integer types, it works how I would expect, but
> for other types it's specified as yielding "the unsigned integer type with
> smallest rank ([conv.rank]) for which sizeof(T) == sizeof(type)". And
> what's confusing to me about that is that it talks about the *size* of the
> type, rather than the *width* of the type, which I think could
> hypothetically lead to getting a type which may have the same size as the
> original type, but which has a smaller width and therefore a smaller value
> range.
> >
> > For instance, we might try to calculate 'make_unsigned_t<char16_t>', and
> let's assume that we're on a platform where char16_t has a size of two
> bytes and a width of 16. To my eye, that call to 'make_unsigned' is not
> required to yield what one might expect, that being the actual underlying
> type of char16_t, 'std::uint_least16_t', nor even a type that has the same
> properties. If we were to imagine that our implementation provides an
> extended unsigned integer type that has a size of two bytes, but which has
> 8 padding bits and a width of 8, then, if I'm understanding all these rules
> correctly, that extended integer type would have to have a lower rank than
> 'std::uint_least16_t', since it has a smaller width. And so according to
> the rules for 'make_unsigned', the implementation would have to yield that
> extended type with the smaller width and the smaller value range before it
> would yield 'std::uint_least16_t', or some other comparable integer type.
> >
> > So what I'm seeking clarification on is, does it actually work this way
> or have I misunderstood something? And if it does work that way, is it
> supposed to? I'd be able to work around this in my code if need be, so it's
> not so big a deal to me, but it has piqued my interest.
> >
> > Thanks
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>

Received on 2026-09-18 17:06:48