C++ Logo

std-discussion

Advanced search

Re: Wondering about the width of integer-class

From: Bingzhi <bingzhi2025_at_[hidden]>
Date: Thu, 29 Oct 2026 06:08:25 +0800
> From: Keenan Horrigan<friedkeenan_at_[hidden]>
> To:"std-discussion_at_[hidden]"
> <std-discussion_at_[hidden]>
> Subject: [std-discussion] Wondering about the width of integer-class
> types
> Message-ID:
> <xrveWmpssPCfJQkUM-HTAK210dMukRfT0o4FvuVZowNwfQ7gnglpPUExiqtSmWFiXQdlAa57-rZ7_L8>
>
> Content-Type: text/plain; charset=utf-8
>
> I was writing a version of 'std::saturating_cast' that would work with integer-class types as well, because I want to saturate-cast to an iterator's difference type, so I was reading where the standard lays out the rules for integer-class types:https://eel.is/c++draft/iterator.concept.winc
>
> In there, it's mentioned that "The width of an integer-class type is greater than that of every integral type of the same signedness", and I was wondering if the "of the same signedness" part really matters? Every (non-bool, non-character) integral type has a corresponding integer type of the opposite signedness which has the same width, and bool and the character types are defined in terms of signed or unsigned integer types, which again should come with a corresponding signed/unsigned version of the same width. So I'm not sure how the signedness of the integer-class type would affect how its width compares to integral types, which makes me worry that I'm missing something.
>
> It's somewhat meaningful to me, since I'm wanting to saturate-cast a 'std::size_t' into the iterator's difference type, and since 'std::size_t' is some unsigned integer type, if all integer-class types have a greater width than all integral types, then theoretically I wouldn't need to even check that the 'std::size_t' value fits into the range of the integer-class type, including in the case where the integer-class type is signed. Because if we say that 'std::size_t' has a width of 'N', then its maximum value is '2^N - 1', and if the integer-class type has a width of 'N + 1', then, in the case that it's signed, its max value would be '2^(N + 1 - 1) - 1', aka '2^N - 1'.
>
> But I could only rely on that if my understanding is correct that the "of the same signedness" part of the sentence from the standard doesn't affect anything. So I was hoping for any clarification on that point.

Yes, that's exactly how it works. And I recommend that anyone who uses
std::ranges::__detail::__max_size_type or __max_diff_size (the only two
integer-class types implemented manually in libstdc++v3; and I can't
find any integer-class type defined in libc++, maybe they're implemented
via _BitInt) should understand how each member function of that
integer-class types works, and you'll find some bugs or maybe it's just
because you can't understand why it works fine ^~^, then you'll find
yourself not sure if they're robust in production code.

I'd rather say that the standard lacks more specification on the
implementation of integer-class types, either by naming them class types
or providing builtin types (seems that the standard doesn't encourage
normal users to use integer-class types).

Received on 2026-10-28 22:08:35