> Oh actually the radix members should be of type int, not bool. I can fix that.
Yes - thank you very much Jonathan for catching that! It was my honest oversight - I am so used to using auto, that I have accidentally copied the wrong type. Also, thank you for adding tests - I should have added them myself in the first place. > Thanks, I don't think there was any reason to omit these members, > and I agree we should add them. Regarding adding missing members, I am wondering whether template specializations of std::numeric_limits<> for integer-class types should define remaining static data members and static member functions, that is: - max_digits10 - traps - is_iec559 - round_style - has_infinity - has_quiet_NaN - has_signaling_NaN - has_denorm - has_denorm_loss - min_exponent - min_exponent10 - max_exponent - max_exponent10 - tinyness_before - epsilon() - round_error() - infinity() - quiet_NaN() - signaling_NaN() - denorm_min() Here are reading relevant sections of the C++ standard: 25.3.4.4 Concept weakly_incrementable [iterator.concept.winc] (5) For every integer-class type I, let B(I) be a unique hypothetical extended integer type of the same signedness with the same width as I. [Note 2: The corresponding hypothetical specialization numeric_limits<B(I)> meets the requirements on numeric_limits specializations for integral types.] (11) For every (possibly cv-qualified) integer-class type I, numeric_limits<I> is specialized such that: - each static data member m has the same value as numeric_limits<B(I)>::m, and - each static member function f returns I(numeric_limits<B(I)>::f()). In short, std::numeric_limits<> specializations for integer-class types should be defined identically to std::numeric_limits<> specializations for extended integer types, and thus define all static data members and static member functions. Am I reading this correctly? Thank you, Mateusz Zych On Wed, Jul 2, 2025 at 1:59 PM Jonathan Wakely <jwak...@redhat.com> wrote: > On 02/07/25 11:52 +0100, Jonathan Wakely wrote: > >On Wed, 2 Jul 2025 at 10:50, Jonathan Wakely <jwak...@redhat.com> wrote: > >> > >> On 02/07/25 03:36 +0300, Mateusz Zych wrote: > >> >Hello libstdc++ Team! > >> > > >> >I have recently found a bug in libstdc++, that is, > >> >the std::numeric_limits<> template specializations for integer-class > types > >> >are missing some of static data members, > >> >which results in compilation errors of valid C++ code: > >> > > >> > - Compiler Explorer: https://godbolt.org/z/E7z4WYfj4 > >> > > >> >Since adding missing member constants, which are the most relevant to > >> >integer-like types, > >> >was not a lot of code, I have prepared a Git patch with relevant > changes. > >> > > >> >I hope this patch is useful, Mateusz Zych > >> > >> Thanks, I don't think there was any reason to omit these members, and I > >> agree we should add them. > >> > >> The patch is simple and obvious enough that I don't think we need a > >> copyright assignment or DCO sign-off, so I'll push this to the > >> relevant branches. Thanks! > > > >Oh actually the radix members should be of type int, not bool. I can fix > that. > > Here's what I'm testing: > > > commit ddd5b88db4fe99166835fe1b94beca451bc1ce30 > Author: Mateusz Zych <mte.z...@gmail.com> > AuthorDate: Tue Jul 1 23:51:40 2025 > Commit: Jonathan Wakely <r...@gcc.gnu.org> > CommitDate: Wed Jul 2 11:57:45 2025 > > libstdc++: Add missing members to numeric_limits specializations for > integer-class types > > [iterator.concept.winc]/11 says that std::numeric_limits should be > specialized for integer-class types, with each member defined > appropriately. > > libstdc++-v3/ChangeLog: > > * include/bits/max_size_type.h > (numeric_limits<__max_size_type>): > New static data members. > (numeric_limits<__max_diff_type>): Likewise. > * testsuite/std/ranges/iota/max_size_type.cc: Check new > members. > > Co-authored-by: Jonathan Wakely <jwak...@redhat.com> > > diff --git a/libstdc++-v3/include/bits/max_size_type.h > b/libstdc++-v3/include/bits/max_size_type.h > index 73a6d141d5bc..3ac2b8e6b878 100644 > --- a/libstdc++-v3/include/bits/max_size_type.h > +++ b/libstdc++-v3/include/bits/max_size_type.h > @@ -775,6 +775,9 @@ namespace ranges > static constexpr bool is_signed = false; > static constexpr bool is_integer = true; > static constexpr bool is_exact = true; > + static constexpr bool is_bounded = true; > + static constexpr bool is_modulo = true; > + static constexpr int radix = 2; > static constexpr int digits > = __gnu_cxx::__int_traits<_Sp::__rep>::__digits + 1; > static constexpr int digits10 > @@ -802,6 +805,9 @@ namespace ranges > static constexpr bool is_signed = true; > static constexpr bool is_integer = true; > static constexpr bool is_exact = true; > + static constexpr bool is_bounded = true; > + static constexpr bool is_modulo = false; > + static constexpr int radix = 2; > static constexpr int digits = numeric_limits<_Sp>::digits - 1; > static constexpr int digits10 > = static_cast<int>(digits * numbers::ln2 / numbers::ln10); > diff --git a/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc > b/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc > index 4739d9e2f790..fc5284594c7e 100644 > --- a/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc > +++ b/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc > @@ -352,6 +352,9 @@ > static_assert(numeric_limits<max_size_t>::is_specialized); > static_assert(!numeric_limits<max_size_t>::is_signed); > static_assert(numeric_limits<max_size_t>::is_integer); > static_assert(numeric_limits<max_size_t>::is_exact); > +static_assert(numeric_limits<max_size_t>::is_bounded); > +static_assert(numeric_limits<max_size_t>::is_modulo); > +static_assert(numeric_limits<max_size_t>::radix == 2); > // We can't unconditionally use numeric_limits here because __int128 is > an > // integral type only in GNU mode. > #if __SIZEOF_INT128__ > @@ -379,6 +382,9 @@ > static_assert(numeric_limits<max_diff_t>::is_specialized); > static_assert(numeric_limits<max_diff_t>::is_signed); > static_assert(numeric_limits<max_diff_t>::is_integer); > static_assert(numeric_limits<max_diff_t>::is_exact); > +static_assert(numeric_limits<max_diff_t>::is_bounded); > +static_assert(!numeric_limits<max_diff_t>::is_modulo); > +static_assert(numeric_limits<max_diff_t>::radix == 2); > static_assert(numeric_limits<max_diff_t>::digits > == numeric_limits<max_size_t>::digits - 1); > static_assert(numeric_limits<max_diff_t>::digits10 > >