On Wed, 2 Jul 2025 at 14:45, Mateusz Zych <mte.z...@gmail.com> wrote:
>
> > 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?

Ah yes, if we're missing those ones too then we need to add them.


>
> 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
>>

Reply via email to