Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #82895 > unrolled thread

C++20 concepts rocks

Started byBonita Montero <Bonita.Montero@gmail.com>
First post2022-02-04 13:54 +0100
Last post2022-02-07 18:30 +0100
Articles 20 on this page of 103 — 18 participants

Back to article view | Back to comp.lang.c++


Contents

  C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-04 13:54 +0100
    Re: C++20 concepts rocks Muttley@dastardlyhq.com - 2022-02-04 14:25 +0000
      Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-04 15:31 +0100
        Re: C++20 concepts rocks Muttley@dastardlyhq.com - 2022-02-04 14:54 +0000
          Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-04 17:41 +0100
            Re: C++20 concepts rocks Muttley@dastardlyhq.com - 2022-02-05 11:31 +0000
              Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-05 12:49 +0100
                Re: C++20 concepts rocks Muttley@dastardlyhq.com - 2022-02-05 12:20 +0000
        Re: C++20 concepts rocks Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-02-04 16:15 +0000
          Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-04 17:43 +0100
          Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-02-05 01:51 +0100
            Re: C++20 concepts rocks Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-02-05 01:59 +0000
            Re: C++20 concepts rocks James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-02-04 23:05 -0500
              Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-02-05 11:56 +0100
                Re: C++20 concepts rocks David Brown <david.brown@hesbynett.no> - 2022-02-05 13:53 +0100
                  Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-02-05 14:12 +0100
                  Re: C++20 concepts rocks Anand Hariharan <mailto.anand.hariharan@gmail.com> - 2022-02-12 11:13 -0800
                    Re: C++20 concepts rocks James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-02-12 22:18 -0500
                      Re: C++20 concepts rocks Richard Damon <Richard@Damon-Family.org> - 2022-02-13 12:51 -0500
                      Re: C++20 concepts rocks Paavo Helde <eesnimi@osa.pri.ee> - 2022-02-13 20:16 +0200
                        Re: C++20 concepts rocks James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-02-13 14:12 -0500
                          Re: C++20 concepts rocks Richard Damon <Richard@Damon-Family.org> - 2022-02-13 16:22 -0500
                            Re: C++20 concepts rocks James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-02-13 17:18 -0500
                            Re: C++20 concepts rocks Öö Tiib <ootiib@hot.ee> - 2022-02-14 00:51 -0800
                              Re: C++20 concepts rocks "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2022-02-14 08:29 -0800
            Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-04 23:37 -0800
              Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-02-05 11:58 +0100
                Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-06 02:16 -0800
              Re: C++20 concepts rocks "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2022-02-05 12:35 -0800
                Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-06 05:54 -0800
                Re: C++20 concepts rocks Manfred <noname@add.invalid> - 2022-02-06 19:43 +0100
          Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-04 23:53 -0800
            Re: C++20 concepts rocks red floyd <no.spam.here@its.invalid> - 2022-02-05 10:10 -0800
              Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-05 19:51 +0100
                Re: C++20 concepts rocks red floyd <no.spam.here@its.invalid> - 2022-02-05 16:42 -0800
                  Re: C++20 concepts rocks Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-02-06 01:39 +0000
                    Re: C++20 concepts rocks red floyd <no.spam.here@its.invalid> - 2022-02-05 18:02 -0800
                  Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-06 09:57 +0100
                    Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-02-06 10:57 +0100
                      Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-06 12:40 +0100
                      Re: C++20 concepts rocks Öö Tiib <ootiib@hot.ee> - 2022-02-06 03:53 -0800
                      Re: C++20 concepts rocks Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-02-06 14:35 +0000
                        Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-06 11:20 -0800
                          Re: C++20 concepts rocks Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-02-06 21:53 +0000
                            Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-06 19:03 -0800
                              Re: C++20 concepts rocks Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-02-07 11:50 +0000
                                Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-07 06:26 -0800
                                  Re: C++20 concepts rocks Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-02-07 15:48 +0000
                                    Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-07 12:16 -0800
                                      Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-07 22:27 -0800
                                      Re: C++20 concepts rocks Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-02-09 21:43 +0000
                                        Re: C++20 concepts rocks James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-02-09 21:07 -0500
                                        Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-09 21:25 -0800
                                          Re: C++20 concepts rocks Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-02-10 13:05 +0000
                                            Re: C++20 concepts rocks James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-02-10 11:19 -0500
                                            Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-11 05:41 -0800
                                              Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-02-11 17:06 +0100
                                                Re: C++20 concepts rocks James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-02-11 11:50 -0500
                                                  Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-02-11 21:13 +0100
                                                Re: C++20 concepts rocks scott@slp53.sl.home (Scott Lurndal) - 2022-02-11 17:06 +0000
                                                Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-15 00:10 -0800
                                                  Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-02-15 20:58 +0100
                                                    Re: C++20 concepts rocks Juha Nieminen <nospam@thanks.invalid> - 2022-02-16 06:40 +0000
                                                      Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-02-16 09:54 +0100
                                                        Re: C++20 concepts rocks Muttley@dastardlyhq.com - 2022-02-16 09:00 +0000
                                                          Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-02-16 20:25 +0100
                                                            Re: C++20 concepts rocks Muttley@dastardlyhq.com - 2022-02-17 08:53 +0000
                                                              Re: C++20 concepts rocks Paavo Helde <eesnimi@osa.pri.ee> - 2022-02-17 16:11 +0200
                                                              Re: C++20 concepts rocks James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-02-17 10:58 -0500
                                                          Re: C++20 concepts rocks Juha Nieminen <nospam@thanks.invalid> - 2022-02-17 07:32 +0000
                                                    Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-04-19 02:21 -0700
                                                      Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-04-19 11:56 +0200
                                                        Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-04-25 03:02 -0700
                                              Re: C++20 concepts rocks Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-02-12 00:01 +0000
                                                Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-14 23:55 -0800
                            Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-07 18:31 +0100
                              Re: C++20 concepts rocks scott@slp53.sl.home (Scott Lurndal) - 2022-02-07 17:43 +0000
                        Re: C++20 concepts rocks James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-02-06 14:25 -0500
                    Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-06 02:01 -0800
                    Re: C++20 concepts rocks red floyd <no.spam.here@its.invalid> - 2022-02-06 19:37 -0800
                      Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-07 10:18 +0100
                      Re: C++20 concepts rocks Paavo Helde <eesnimi@osa.pri.ee> - 2022-02-07 11:32 +0200
                        Re: C++20 concepts rocks red floyd <no.spam.here@its.invalid> - 2022-02-07 07:55 -0800
              Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-06 02:11 -0800
                Re: C++20 concepts rocks "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-02-06 13:13 +0100
                  Re: C++20 concepts rocks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-06 04:58 -0800
                    Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-06 14:08 +0100
          Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-05 12:48 +0100
      Re: C++20 concepts rocks Juha Nieminen <nospam@thanks.invalid> - 2022-02-04 20:15 +0000
        Re: C++20 concepts rocks Muttley@dastardlyhq.com - 2022-02-05 11:32 +0000
          Re: C++20 concepts rocks Juha Nieminen <nospam@thanks.invalid> - 2022-02-06 08:28 +0000
            Re: C++20 concepts rocks Muttley@dastardlyhq.com - 2022-02-07 09:52 +0000
              Re: C++20 concepts rocks Juha Nieminen <nospam@thanks.invalid> - 2022-02-08 07:05 +0000
                Re: C++20 concepts rocks Muttley@dastardlyhq.com - 2022-02-08 09:25 +0000
                  Re: C++20 concepts rocks Juha Nieminen <nospam@thanks.invalid> - 2022-02-08 10:09 +0000
    Re: C++20 concepts rocks Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-02-04 12:10 -0800
      Re: C++20 concepts rocks Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-05 13:41 +0100
        Re: C++20 concepts rocks "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2022-02-05 19:28 -0800
    A little benchmark: Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-05 13:22 +0100
      A better benchmark Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-06 14:56 +0100
        A improved routine Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-07 15:19 +0100
        Re: A better benchmark Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-02-07 06:57 -0800
          Re: A better benchmark Bonita Montero <Bonita.Montero@gmail.com> - 2022-02-07 18:30 +0100

Page 1 of 6  [1] 2 3 4 5 6  Next page →


#82895 — C++20 concepts rocks

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-02-04 13:54 +0100
SubjectC++20 concepts rocks
Message-ID<stj7m4$bim$1@dont-email.me>
I've just written a small routine:

template<typename StringType>
	requires is_same_v<StringType, basic_string<typename 
StringType::value_type, typename StringType::traits_type, typename 
StringType::allocator_type>>
StringType formatClockCycles( uint64_t clockCycles )
{
	using dig_arr_t = array<uint8_t, 20>; // max 20 digits for 64 bit
	using dig_arr_it = dig_arr_t::iterator;
	dig_arr_t reverseDigits;
	dig_arr_it rDigitsEnd = reverseDigits.begin();
	do
		*rDigitsEnd++ = clockCycles % 10,
		clockCycles /= 10;
	while( clockCycles );
	size_t
		digitsLen = rDigitsEnd - reverseDigits.begin(),
		groups = (digitsLen - 1) / 3;
	StringType str( digitsLen + groups, '\0' );
	typename StringType::iterator wrt = str.end();
	dig_arr_it digit = reverseDigits.begin();
	for( dig_arr_it groupsEnd = reverseDigits.begin() + groups * 3; digit 
!= groupsEnd; wrt -= 4, digit += 3 )
		wrt[-1] = digit[0] + '0',
		wrt[-2] = digit[1] + '0',
		wrt[-3] = digit[2] + '0',
		wrt[-4] = '.';
	do
		*--wrt = *digit++ + '0';
	while( digit != rDigitsEnd );
	return str;
}

The cool thing here that the concept above doesn't have an error if
...::value_type, ...::traits_type and ...::allocator_type are missing;
I just get an error as if I'd also included a check for the existence
of these types.

[toc] | [next] | [standalone]


#82896

FromMuttley@dastardlyhq.com
Date2022-02-04 14:25 +0000
Message-ID<stjd0m$1380$1@gioia.aioe.org>
In reply to#82895
On Fri, 4 Feb 2022 13:54:27 +0100
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>I've just written a small routine:
>
>template<typename StringType>
>	requires is_same_v<StringType, basic_string<typename 
>StringType::value_type, typename StringType::traits_type, typename 
>StringType::allocator_type>>
>StringType formatClockCycles( uint64_t clockCycles )

Some C++ prototypes are almost comical they're so unreadable.

>	using dig_arr_t = array<uint8_t, 20>; // max 20 digits for 64 bit
>	using dig_arr_it = dig_arr_t::iterator;
>	dig_arr_t reverseDigits;
>	dig_arr_it rDigitsEnd = reverseDigits.begin();
>	do
>		*rDigitsEnd++ = clockCycles % 10,
>		clockCycles /= 10;
>	while( clockCycles );
>	size_t
>		digitsLen = rDigitsEnd - reverseDigits.begin(),
>		groups = (digitsLen - 1) / 3;
>	StringType str( digitsLen + groups, '\0' );
>	typename StringType::iterator wrt = str.end();
>	dig_arr_it digit = reverseDigits.begin();
>	for( dig_arr_it groupsEnd = reverseDigits.begin() + groups * 3; digit 
>!= groupsEnd; wrt -= 4, digit += 3 )
>		wrt[-1] = digit[0] + '0',
>		wrt[-2] = digit[1] + '0',
>		wrt[-3] = digit[2] + '0',
>		wrt[-4] = '.';
>	do
>		*--wrt = *digit++ + '0';
>	while( digit != rDigitsEnd );
>	return str;
>}
>
>The cool thing here that the concept above doesn't have an error if
>....::value_type, ...::traits_type and ...::allocator_type are missing;
>I just get an error as if I'd also included a check for the existence
>of these types.

Thats nice. Personally I'd just use printf().

[toc] | [prev] | [next] | [standalone]


#82897

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-02-04 15:31 +0100
Message-ID<stjdbe$7th$1@dont-email.me>
In reply to#82896
Am 04.02.2022 um 15:25 schrieb Muttley@dastardlyhq.com:
> On Fri, 4 Feb 2022 13:54:27 +0100
> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>> I've just written a small routine:
>>
>> template<typename StringType>
>> 	requires is_same_v<StringType, basic_string<typename
>> StringType::value_type, typename StringType::traits_type, typename
>> StringType::allocator_type>>
>> StringType formatClockCycles( uint64_t clockCycles )
> 
> Some C++ prototypes are almost comical they're so unreadable.

For those who are familiar with concepts that's readable.

>> 	using dig_arr_t = array<uint8_t, 20>; // max 20 digits for 64 bit
>> 	using dig_arr_it = dig_arr_t::iterator;
>> 	dig_arr_t reverseDigits;
>> 	dig_arr_it rDigitsEnd = reverseDigits.begin();
>> 	do
>> 		*rDigitsEnd++ = clockCycles % 10,
>> 		clockCycles /= 10;
>> 	while( clockCycles );
>> 	size_t
>> 		digitsLen = rDigitsEnd - reverseDigits.begin(),
>> 		groups = (digitsLen - 1) / 3;
>> 	StringType str( digitsLen + groups, '\0' );
>> 	typename StringType::iterator wrt = str.end();
>> 	dig_arr_it digit = reverseDigits.begin();
>> 	for( dig_arr_it groupsEnd = reverseDigits.begin() + groups * 3; digit
>> != groupsEnd; wrt -= 4, digit += 3 )
>> 		wrt[-1] = digit[0] + '0',
>> 		wrt[-2] = digit[1] + '0',
>> 		wrt[-3] = digit[2] + '0',
>> 		wrt[-4] = '.';
>> 	do
>> 		*--wrt = *digit++ + '0';
>> 	while( digit != rDigitsEnd );
>> 	return str;
>> }
>>
>> The cool thing here that the concept above doesn't have an error if
>> ....::value_type, ...::traits_type and ...::allocator_type are missing;
>> I just get an error as if I'd also included a check for the existence
>> of these types.
> 
> Thats nice. Personally I'd just use printf().

You can't do what I did with (s)printf().

[toc] | [prev] | [next] | [standalone]


#82898

FromMuttley@dastardlyhq.com
Date2022-02-04 14:54 +0000
Message-ID<stjenr$1t4l$1@gioia.aioe.org>
In reply to#82897
On Fri, 4 Feb 2022 15:31:09 +0100
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>Am 04.02.2022 um 15:25 schrieb Muttley@dastardlyhq.com:
>> On Fri, 4 Feb 2022 13:54:27 +0100
>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> I've just written a small routine:
>>>
>>> template<typename StringType>
>>> 	requires is_same_v<StringType, basic_string<typename
>>> StringType::value_type, typename StringType::traits_type, typename
>>> StringType::allocator_type>>
>>> StringType formatClockCycles( uint64_t clockCycles )
>> 
>> Some C++ prototypes are almost comical they're so unreadable.
>
>For those who are familiar with concepts that's readable.

It really isn't.

>>> 	using dig_arr_t = array<uint8_t, 20>; // max 20 digits for 64 bit
>>> 	using dig_arr_it = dig_arr_t::iterator;
>>> 	dig_arr_t reverseDigits;
>>> 	dig_arr_it rDigitsEnd = reverseDigits.begin();
>>> 	do
>>> 		*rDigitsEnd++ = clockCycles % 10,
>>> 		clockCycles /= 10;
>>> 	while( clockCycles );
>>> 	size_t
>>> 		digitsLen = rDigitsEnd - reverseDigits.begin(),
>>> 		groups = (digitsLen - 1) / 3;
>>> 	StringType str( digitsLen + groups, '\0' );
>>> 	typename StringType::iterator wrt = str.end();
>>> 	dig_arr_it digit = reverseDigits.begin();
>>> 	for( dig_arr_it groupsEnd = reverseDigits.begin() + groups * 3; digit
>>> != groupsEnd; wrt -= 4, digit += 3 )
>>> 		wrt[-1] = digit[0] + '0',
>>> 		wrt[-2] = digit[1] + '0',
>>> 		wrt[-3] = digit[2] + '0',
>>> 		wrt[-4] = '.';
>>> 	do
>>> 		*--wrt = *digit++ + '0';
>>> 	while( digit != rDigitsEnd );
>>> 	return str;
>>> }
>>>
>>> The cool thing here that the concept above doesn't have an error if
>>> ....::value_type, ...::traits_type and ...::allocator_type are missing;
>>> I just get an error as if I'd also included a check for the existence
>>> of these types.
>> 
>> Thats nice. Personally I'd just use printf().
>
>You can't do what I did with (s)printf().

I have no idea, my compiler isn't 2020 so I can't even compile it. But it
looks like nothing more than a number formatter.

[toc] | [prev] | [next] | [standalone]


#82900

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-02-04 17:41 +0100
Message-ID<stjkvo$o3j$1@dont-email.me>
In reply to#82898
Am 04.02.2022 um 15:54 schrieb Muttley@dastardlyhq.com:
> On Fri, 4 Feb 2022 15:31:09 +0100
> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>> Am 04.02.2022 um 15:25 schrieb Muttley@dastardlyhq.com:
>>> On Fri, 4 Feb 2022 13:54:27 +0100
>>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> I've just written a small routine:
>>>>
>>>> template<typename StringType>
>>>> 	requires is_same_v<StringType, basic_string<typename
>>>> StringType::value_type, typename StringType::traits_type, typename
>>>> StringType::allocator_type>>
>>>> StringType formatClockCycles( uint64_t clockCycles )
>>>
>>> Some C++ prototypes are almost comical they're so unreadable.
>>
>> For those who are familiar with concepts that's readable.
> 
> It really isn't.

That's just an opinion of an under-skilled developer.

>>>> 	using dig_arr_t = array<uint8_t, 20>; // max 20 digits for 64 bit
>>>> 	using dig_arr_it = dig_arr_t::iterator;
>>>> 	dig_arr_t reverseDigits;
>>>> 	dig_arr_it rDigitsEnd = reverseDigits.begin();
>>>> 	do
>>>> 		*rDigitsEnd++ = clockCycles % 10,
>>>> 		clockCycles /= 10;
>>>> 	while( clockCycles );
>>>> 	size_t
>>>> 		digitsLen = rDigitsEnd - reverseDigits.begin(),
>>>> 		groups = (digitsLen - 1) / 3;
>>>> 	StringType str( digitsLen + groups, '\0' );
>>>> 	typename StringType::iterator wrt = str.end();
>>>> 	dig_arr_it digit = reverseDigits.begin();
>>>> 	for( dig_arr_it groupsEnd = reverseDigits.begin() + groups * 3; digit
>>>> != groupsEnd; wrt -= 4, digit += 3 )
>>>> 		wrt[-1] = digit[0] + '0',
>>>> 		wrt[-2] = digit[1] + '0',
>>>> 		wrt[-3] = digit[2] + '0',
>>>> 		wrt[-4] = '.';
>>>> 	do
>>>> 		*--wrt = *digit++ + '0';
>>>> 	while( digit != rDigitsEnd );
>>>> 	return str;
>>>> }
>>>>
>>>> The cool thing here that the concept above doesn't have an error if
>>>> ....::value_type, ...::traits_type and ...::allocator_type are missing;
>>>> I just get an error as if I'd also included a check for the existence
>>>> of these types.
>>>
>>> Thats nice. Personally I'd just use printf().
>>
>> You can't do what I did with (s)printf().
> 
> I have no idea, my compiler isn't 2020 so I can't even compile it.
>. But it looks like nothing more than a number formatter.

Of course it is a formater, but I don't have to ask myself
why you don't understand what it does.

[toc] | [prev] | [next] | [standalone]


#82911

FromMuttley@dastardlyhq.com
Date2022-02-05 11:31 +0000
Message-ID<stln6n$1g7f$1@gioia.aioe.org>
In reply to#82900
On Fri, 4 Feb 2022 17:41:27 +0100
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>Am 04.02.2022 um 15:54 schrieb Muttley@dastardlyhq.com:
>> On Fri, 4 Feb 2022 15:31:09 +0100
>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> Am 04.02.2022 um 15:25 schrieb Muttley@dastardlyhq.com:
>>>> On Fri, 4 Feb 2022 13:54:27 +0100
>>>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>>> I've just written a small routine:
>>>>>
>>>>> template<typename StringType>
>>>>> 	requires is_same_v<StringType, basic_string<typename
>>>>> StringType::value_type, typename StringType::traits_type, typename
>>>>> StringType::allocator_type>>
>>>>> StringType formatClockCycles( uint64_t clockCycles )
>>>>
>>>> Some C++ prototypes are almost comical they're so unreadable.
>>>
>>> For those who are familiar with concepts that's readable.
>> 
>> It really isn't.
>
>That's just an opinion of an under-skilled developer.

Yes, this under skilled developer who wrote networking code to link a major
US bank to various european stock exchanges back in the 00s while you were 
probably still having your arse wiped by your mother. Thats before I moved
in to aerospace and defense.

Unlike you and various others on here I'm not impressed by obscure unreadable 
unmaintanable "Look at me, I'm so clever" code designed simply to show off. 
I've had to manage coders like you and the bug ridden poorly designed crap you 
that usually ends up being rewritten in a sane manner for reliability.

HTH.

[toc] | [prev] | [next] | [standalone]


#82914

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-02-05 12:49 +0100
Message-ID<stlo8d$s9s$2@dont-email.me>
In reply to#82911
Am 05.02.2022 um 12:31 schrieb Muttley@dastardlyhq.com:

> ... Thats before I moved in to aerospace and defense.

According to what you said you're not in aerospace and defense
but most likely supported by the social service.

[toc] | [prev] | [next] | [standalone]


#82915

FromMuttley@dastardlyhq.com
Date2022-02-05 12:20 +0000
Message-ID<stlq2v$no7$1@gioia.aioe.org>
In reply to#82914
On Sat, 5 Feb 2022 12:49:34 +0100
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>Am 05.02.2022 um 12:31 schrieb Muttley@dastardlyhq.com:
>
>> ... Thats before I moved in to aerospace and defense.
>
>According to what you said you're not in aerospace and defense
>but most likely supported by the social service.

Believe what you like little girl. No doubt you'll have a career in academia 
making a lot of noise but achieving nothing.

[toc] | [prev] | [next] | [standalone]


#82899

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2022-02-04 16:15 +0000
Message-ID<87k0easj5d.fsf@bsb.me.uk>
In reply to#82897
Bonita Montero <Bonita.Montero@gmail.com> writes:

> Am 04.02.2022 um 15:25 schrieb Muttley@dastardlyhq.com:
>> On Fri, 4 Feb 2022 13:54:27 +0100
>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> I've just written a small routine:
>>>
>>> template<typename StringType>
>>> 	requires is_same_v<StringType, basic_string<typename
>>> StringType::value_type, typename StringType::traits_type, typename
>>> StringType::allocator_type>>
>>> StringType formatClockCycles( uint64_t clockCycles )
>> Some C++ prototypes are almost comical they're so unreadable.
>
> For those who are familiar with concepts that's readable.
>
>>> 	using dig_arr_t = array<uint8_t, 20>; // max 20 digits for 64 bit
>>> 	using dig_arr_it = dig_arr_t::iterator;
>>> 	dig_arr_t reverseDigits;
>>> 	dig_arr_it rDigitsEnd = reverseDigits.begin();
>>> 	do
>>> 		*rDigitsEnd++ = clockCycles % 10,
>>> 		clockCycles /= 10;
>>> 	while( clockCycles );
>>> 	size_t
>>> 		digitsLen = rDigitsEnd - reverseDigits.begin(),
>>> 		groups = (digitsLen - 1) / 3;
>>> 	StringType str( digitsLen + groups, '\0' );
>>> 	typename StringType::iterator wrt = str.end();
>>> 	dig_arr_it digit = reverseDigits.begin();
>>> 	for( dig_arr_it groupsEnd = reverseDigits.begin() + groups * 3; digit
>>> != groupsEnd; wrt -= 4, digit += 3 )
>>> 		wrt[-1] = digit[0] + '0',
>>> 		wrt[-2] = digit[1] + '0',
>>> 		wrt[-3] = digit[2] + '0',
>>> 		wrt[-4] = '.';
>>> 	do
>>> 		*--wrt = *digit++ + '0';
>>> 	while( digit != rDigitsEnd );
>>> 	return str;
>>> }
>>>
>>> The cool thing here that the concept above doesn't have an error if
>>> ....::value_type, ...::traits_type and ...::allocator_type are missing;
>>> I just get an error as if I'd also included a check for the existence
>>> of these types.
>> Thats nice. Personally I'd just use printf().
>
> You can't do what I did with (s)printf().

template<typename StringType>
requires is_same_v<StringType,
                   basic_string<typename StringType::value_type,
                                typename StringType::traits_type,
                                typename StringType::allocator_type>>
StringType formatClockCycles(uint64_t clockCycles)
{
   char result[28], *ep = (&result)[1];
   do {
      sprintf(ep - 4, "%03lu", clockCycles % 1000);
      if (ep != (&result)[1]) ep[-1] = '.';
      ep -= 4;
   } while (clockCycles /= 1000);
   while (*ep == '0' && ep[1]) ep++;
   return ep;
}

(the appropriate comment on the 28 is left as an exercise to the reader!)

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#82901

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-02-04 17:43 +0100
Message-ID<stjl37$o3j$2@dont-email.me>
In reply to#82899
Am 04.02.2022 um 17:15 schrieb Ben Bacarisse:
> Bonita Montero <Bonita.Montero@gmail.com> writes:
> 
>> Am 04.02.2022 um 15:25 schrieb Muttley@dastardlyhq.com:
>>> On Fri, 4 Feb 2022 13:54:27 +0100
>>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> I've just written a small routine:
>>>>
>>>> template<typename StringType>
>>>> 	requires is_same_v<StringType, basic_string<typename
>>>> StringType::value_type, typename StringType::traits_type, typename
>>>> StringType::allocator_type>>
>>>> StringType formatClockCycles( uint64_t clockCycles )
>>> Some C++ prototypes are almost comical they're so unreadable.
>>
>> For those who are familiar with concepts that's readable.
>>
>>>> 	using dig_arr_t = array<uint8_t, 20>; // max 20 digits for 64 bit
>>>> 	using dig_arr_it = dig_arr_t::iterator;
>>>> 	dig_arr_t reverseDigits;
>>>> 	dig_arr_it rDigitsEnd = reverseDigits.begin();
>>>> 	do
>>>> 		*rDigitsEnd++ = clockCycles % 10,
>>>> 		clockCycles /= 10;
>>>> 	while( clockCycles );
>>>> 	size_t
>>>> 		digitsLen = rDigitsEnd - reverseDigits.begin(),
>>>> 		groups = (digitsLen - 1) / 3;
>>>> 	StringType str( digitsLen + groups, '\0' );
>>>> 	typename StringType::iterator wrt = str.end();
>>>> 	dig_arr_it digit = reverseDigits.begin();
>>>> 	for( dig_arr_it groupsEnd = reverseDigits.begin() + groups * 3; digit
>>>> != groupsEnd; wrt -= 4, digit += 3 )
>>>> 		wrt[-1] = digit[0] + '0',
>>>> 		wrt[-2] = digit[1] + '0',
>>>> 		wrt[-3] = digit[2] + '0',
>>>> 		wrt[-4] = '.';
>>>> 	do
>>>> 		*--wrt = *digit++ + '0';
>>>> 	while( digit != rDigitsEnd );
>>>> 	return str;
>>>> }
>>>>
>>>> The cool thing here that the concept above doesn't have an error if
>>>> ....::value_type, ...::traits_type and ...::allocator_type are missing;
>>>> I just get an error as if I'd also included a check for the existence
>>>> of these types.
>>> Thats nice. Personally I'd just use printf().
>>
>> You can't do what I did with (s)printf().
> 
> template<typename StringType>
> requires is_same_v<StringType,
>                     basic_string<typename StringType::value_type,
>                                  typename StringType::traits_type,
>                                  typename StringType::allocator_type>>
> StringType formatClockCycles(uint64_t clockCycles)
> {
>     char result[28], *ep = (&result)[1];
>     do {
>        sprintf(ep - 4, "%03lu", clockCycles % 1000);
>        if (ep != (&result)[1]) ep[-1] = '.';
>        ep -= 4;
>     } while (clockCycles /= 1000);
>     while (*ep == '0' && ep[1]) ep++;
>     return ep;
> }
> 
> (the appropriate comment on the 28 is left as an exercise to the reader!)

That's shorter, but for sure not as fast.

[toc] | [prev] | [next] | [standalone]


#82904

From"Alf P. Steinbach" <alf.p.steinbach@gmail.com>
Date2022-02-05 01:51 +0100
Message-ID<stkhn8$2b6$1@dont-email.me>
In reply to#82899
On 4 Feb 2022 17:15, Ben Bacarisse wrote:
> Bonita Montero <Bonita.Montero@gmail.com> writes:
> 
>> Am 04.02.2022 um 15:25 schrieb Muttley@dastardlyhq.com:
>>> On Fri, 4 Feb 2022 13:54:27 +0100
>>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> I've just written a small routine:
>>>>
>>>> template<typename StringType>
>>>> 	requires is_same_v<StringType, basic_string<typename
>>>> StringType::value_type, typename StringType::traits_type, typename
>>>> StringType::allocator_type>>
>>>> StringType formatClockCycles( uint64_t clockCycles )
>>> Some C++ prototypes are almost comical they're so unreadable.
>>
>> For those who are familiar with concepts that's readable.
>>
>>>> 	using dig_arr_t = array<uint8_t, 20>; // max 20 digits for 64 bit
>>>> 	using dig_arr_it = dig_arr_t::iterator;
>>>> 	dig_arr_t reverseDigits;
>>>> 	dig_arr_it rDigitsEnd = reverseDigits.begin();
>>>> 	do
>>>> 		*rDigitsEnd++ = clockCycles % 10,
>>>> 		clockCycles /= 10;
>>>> 	while( clockCycles );
>>>> 	size_t
>>>> 		digitsLen = rDigitsEnd - reverseDigits.begin(),
>>>> 		groups = (digitsLen - 1) / 3;
>>>> 	StringType str( digitsLen + groups, '\0' );
>>>> 	typename StringType::iterator wrt = str.end();
>>>> 	dig_arr_it digit = reverseDigits.begin();
>>>> 	for( dig_arr_it groupsEnd = reverseDigits.begin() + groups * 3; digit
>>>> != groupsEnd; wrt -= 4, digit += 3 )
>>>> 		wrt[-1] = digit[0] + '0',
>>>> 		wrt[-2] = digit[1] + '0',
>>>> 		wrt[-3] = digit[2] + '0',
>>>> 		wrt[-4] = '.';
>>>> 	do
>>>> 		*--wrt = *digit++ + '0';
>>>> 	while( digit != rDigitsEnd );
>>>> 	return str;
>>>> }
>>>>
>>>> The cool thing here that the concept above doesn't have an error if
>>>> ....::value_type, ...::traits_type and ...::allocator_type are missing;
>>>> I just get an error as if I'd also included a check for the existence
>>>> of these types.
>>> Thats nice. Personally I'd just use printf().
>>
>> You can't do what I did with (s)printf().
> 
> template<typename StringType>
> requires is_same_v<StringType,
>                     basic_string<typename StringType::value_type,
>                                  typename StringType::traits_type,
>                                  typename StringType::allocator_type>>
> StringType formatClockCycles(uint64_t clockCycles)
> {
>     char result[28], *ep = (&result)[1];
>     do {
>        sprintf(ep - 4, "%03lu", clockCycles % 1000);
>        if (ep != (&result)[1]) ep[-1] = '.';
>        ep -= 4;
>     } while (clockCycles /= 1000);
>     while (*ep == '0' && ep[1]) ep++;
>     return ep;
> }
> 
> (the appropriate comment on the 28 is left as an exercise to the reader!)
> 

Nice, but I believe it's formal UB to move a pointer to `char` from 
beyond an array into the array, and dereference it.

The C committee wrote a rationale for their earlier decision to make it 
so, instead of admitting that it was bludner. Uh, blunder. I don't 
recall who provided that information, but someone in this group.

Nice for C: the current C++ committee is doing far worse things, so bad 
that they provoked a scathing article (remember the Vasa!) from the 
language creator -- to no avail, they continued to do even worse. So. 
Maybe it's a good idea to just adhere to some /de facto/ standard.


- Alf

[toc] | [prev] | [next] | [standalone]


#82905

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2022-02-05 01:59 +0000
Message-ID<87ee4irs3v.fsf@bsb.me.uk>
In reply to#82904
"Alf P. Steinbach" <alf.p.steinbach@gmail.com> writes:

> On 4 Feb 2022 17:15, Ben Bacarisse wrote:
>> Bonita Montero <Bonita.Montero@gmail.com> writes:
>> 
>>> Am 04.02.2022 um 15:25 schrieb Muttley@dastardlyhq.com:
>>>> On Fri, 4 Feb 2022 13:54:27 +0100
>>>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>>> I've just written a small routine:
>>>>>
>>>>> template<typename StringType>
>>>>> 	requires is_same_v<StringType, basic_string<typename
>>>>> StringType::value_type, typename StringType::traits_type, typename
>>>>> StringType::allocator_type>>
>>>>> StringType formatClockCycles( uint64_t clockCycles )
>>>> Some C++ prototypes are almost comical they're so unreadable.
>>>
>>> For those who are familiar with concepts that's readable.
>>>
>>>>> 	using dig_arr_t = array<uint8_t, 20>; // max 20 digits for 64 bit
>>>>> 	using dig_arr_it = dig_arr_t::iterator;
>>>>> 	dig_arr_t reverseDigits;
>>>>> 	dig_arr_it rDigitsEnd = reverseDigits.begin();
>>>>> 	do
>>>>> 		*rDigitsEnd++ = clockCycles % 10,
>>>>> 		clockCycles /= 10;
>>>>> 	while( clockCycles );
>>>>> 	size_t
>>>>> 		digitsLen = rDigitsEnd - reverseDigits.begin(),
>>>>> 		groups = (digitsLen - 1) / 3;
>>>>> 	StringType str( digitsLen + groups, '\0' );
>>>>> 	typename StringType::iterator wrt = str.end();
>>>>> 	dig_arr_it digit = reverseDigits.begin();
>>>>> 	for( dig_arr_it groupsEnd = reverseDigits.begin() + groups * 3; digit
>>>>> != groupsEnd; wrt -= 4, digit += 3 )
>>>>> 		wrt[-1] = digit[0] + '0',
>>>>> 		wrt[-2] = digit[1] + '0',
>>>>> 		wrt[-3] = digit[2] + '0',
>>>>> 		wrt[-4] = '.';
>>>>> 	do
>>>>> 		*--wrt = *digit++ + '0';
>>>>> 	while( digit != rDigitsEnd );
>>>>> 	return str;
>>>>> }
>>>>>
>>>>> The cool thing here that the concept above doesn't have an error if
>>>>> ....::value_type, ...::traits_type and ...::allocator_type are missing;
>>>>> I just get an error as if I'd also included a check for the existence
>>>>> of these types.
>>>> Thats nice. Personally I'd just use printf().
>>>
>>> You can't do what I did with (s)printf().
>> template<typename StringType>
>> requires is_same_v<StringType,
>>                     basic_string<typename StringType::value_type,
>>                                  typename StringType::traits_type,
>>                                  typename StringType::allocator_type>>
>> StringType formatClockCycles(uint64_t clockCycles)
>> {
>>     char result[28], *ep = (&result)[1];
>>     do {
>>        sprintf(ep - 4, "%03lu", clockCycles % 1000);
>>        if (ep != (&result)[1]) ep[-1] = '.';
>>        ep -= 4;
>>     } while (clockCycles /= 1000);
>>     while (*ep == '0' && ep[1]) ep++;
>>     return ep;
>> }
>> (the appropriate comment on the 28 is left as an exercise to the reader!)
>> 
>
> Nice, but I believe it's formal UB to move a pointer to `char` from
> beyond an array into the array, and dereference it.

Which bit is UB?  I don't see any such deference but I've not spent much
time looking.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#82906

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-02-04 23:05 -0500
Message-ID<stkt1v$poe$1@dont-email.me>
In reply to#82904
On 2/4/22 19:51, Alf P. Steinbach wrote:
> On 4 Feb 2022 17:15, Ben Bacarisse wrote:
...
>> template<typename StringType>
>> requires is_same_v<StringType,
>>                     basic_string<typename StringType::value_type,
>>                                  typename StringType::traits_type,
>>                                  typename StringType::allocator_type>>
>> StringType formatClockCycles(uint64_t clockCycles)
>> {
>>     char result[28], *ep = (&result)[1];
>>     do {
>>        sprintf(ep - 4, "%03lu", clockCycles % 1000);
>>        if (ep != (&result)[1]) ep[-1] = '.';
>>        ep -= 4;
>>     } while (clockCycles /= 1000);
>>     while (*ep == '0' && ep[1]) ep++;
>>     return ep;
>> }
>>
>> (the appropriate comment on the 28 is left as an exercise to the reader!)
>>
> 
> Nice, but I believe it's formal UB to move a pointer to `char` from 
> beyond an array into the array, and dereference it.

Citation please? I can't find any such prohibition. I can find clauses
that describe how such code is required to work:

"For purposes of pointer arithmetic (7.6.6) and comparison (7.6.9,
7.6.10), a pointer past the end of the last element of an array x of n
elements is considered to be equivalent to a pointer to a hypothetical
array element n of x ..." (6.8.2p3)

"When an expression J that has integral type is added to or subtracted
from an expression P of pointer type, the result has the type of P.
...
— Otherwise, if P points to an array element i of an array object x with
n elements (9.3.3.4), 76 the expressions P + J and J + P (where J has
the value j) point to the (possibly-hypothetical) array element i + j of
x if 0 ≤ i + j ≤ n and the expression P - J points to the
(possibly-hypothetical) array element i − j of x if 0 ≤ i − j ≤ n.
— Otherwise, the behavior is undefined." (7.6.6p4).

The "76" in the middle of that citation is refers to footnote 76, which
says

"... a pointer past the last element of an array of n elements is
considered to be equivalent to a pointer to a hypothetical array
element n for this purpose."

Note that the behavior is NOT undefined if the result of the addition or
subtraction is a pointer that points at the hypothetical element one
past the end of the array. Since it is only a hypothetical element, such
a pointer cannot be derefrenced. However, per footnote 76, it is also
permissible to start from such a pointer and move it back into the
array, and there's no clause that I'm aware of that prohibits
dereferencing the resulting pointer .


> The C committee wrote a rationale for their earlier decision to make it 
> so, instead of admitting that it was bludner. Uh, blunder. I don't 
> recall who provided that information, but someone in this group.

Creating a pointer one past the end of an array is needed for the common
idiom of denoting a range of array elements by providing two pointers:
the first points at the beginning of the first element of range, while
the second points at the end of the last element in the range. If it
were not permissible to create a pointer one past the end of an array,
you could not use that idiom to create a pair of pointers that describes
a range that includes the last element of the array.

Furthermore, having passed such a pair of pointers to an algorithm, it's
up to that algorithm how it works its way to the individual elements of
that range. For many algorithms, the most sensible approach includes
moving the end pointer towards the beginning pointer, rather than
vice-versa. If it weren't permissible to take a pointer one past the end
of an array, and move it back into that array, such algorithms could not
be used on ranges that include the last element of the array.

I'm puzzled how you could consider it a blunder to allow these things.
The amount of code that would break if they were disallowed would be
enormous.

[toc] | [prev] | [next] | [standalone]


#82909

From"Alf P. Steinbach" <alf.p.steinbach@gmail.com>
Date2022-02-05 11:56 +0100
Message-ID<stll5s$ao6$1@dont-email.me>
In reply to#82906
On 5 Feb 2022 05:05, James Kuyper wrote:
> On 2/4/22 19:51, Alf P. Steinbach wrote:
>> On 4 Feb 2022 17:15, Ben Bacarisse wrote:
> ...
>>> template<typename StringType>
>>> requires is_same_v<StringType,
>>>                      basic_string<typename StringType::value_type,
>>>                                   typename StringType::traits_type,
>>>                                   typename StringType::allocator_type>>
>>> StringType formatClockCycles(uint64_t clockCycles)
>>> {
>>>      char result[28], *ep = (&result)[1];
>>>      do {
>>>         sprintf(ep - 4, "%03lu", clockCycles % 1000);
>>>         if (ep != (&result)[1]) ep[-1] = '.';
>>>         ep -= 4;
>>>      } while (clockCycles /= 1000);
>>>      while (*ep == '0' && ep[1]) ep++;
>>>      return ep;
>>> }
>>>
>>> (the appropriate comment on the 28 is left as an exercise to the reader!)
>>>
>>
>> Nice, but I believe it's formal UB to move a pointer to `char` from
>> beyond an array into the array, and dereference it.
> 
> Citation please? I can't find any such prohibition. I can find clauses
> that describe how such code is required to work:
> 
> "For purposes of pointer arithmetic (7.6.6) and comparison (7.6.9,
> 7.6.10), a pointer past the end of the last element of an array x of n
> elements is considered to be equivalent to a pointer to a hypothetical
> array element n of x ..." (6.8.2p3)
> 
> "When an expression J that has integral type is added to or subtracted
> from an expression P of pointer type, the result has the type of P.
> ...
> — Otherwise, if P points to an array element i of an array object x with
> n elements (9.3.3.4), 76 the expressions P + J and J + P (where J has
> the value j) point to the (possibly-hypothetical) array element i + j of
> x if 0 ≤ i + j ≤ n and the expression P - J points to the
> (possibly-hypothetical) array element i − j of x if 0 ≤ i − j ≤ n.
> — Otherwise, the behavior is undefined." (7.6.6p4).
> 
> The "76" in the middle of that citation is refers to footnote 76, which
> says
> 
> "... a pointer past the last element of an array of n elements is
> considered to be equivalent to a pointer to a hypothetical array
> element n for this purpose."
> 
> Note that the behavior is NOT undefined if the result of the addition or
> subtraction is a pointer that points at the hypothetical element one
> past the end of the array. Since it is only a hypothetical element, such
> a pointer cannot be derefrenced. However, per footnote 76, it is also
> permissible to start from such a pointer and move it back into the
> array, and there's no clause that I'm aware of that prohibits
> dereferencing the resulting pointer .
> 
> 
>> The C committee wrote a rationale for their earlier decision to make it
>> so, instead of admitting that it was bludner. Uh, blunder. I don't
>> recall who provided that information, but someone in this group.
> 
> Creating a pointer one past the end of an array is needed for the common
> idiom of denoting a range of array elements by providing two pointers:
> the first points at the beginning of the first element of range, while
> the second points at the end of the last element in the range. If it
> were not permissible to create a pointer one past the end of an array,
> you could not use that idiom to create a pair of pointers that describes
> a range that includes the last element of the array.
> 
> Furthermore, having passed such a pair of pointers to an algorithm, it's
> up to that algorithm how it works its way to the individual elements of
> that range. For many algorithms, the most sensible approach includes
> moving the end pointer towards the beginning pointer, rather than
> vice-versa. If it weren't permissible to take a pointer one past the end
> of an array, and move it back into that array, such algorithms could not
> be used on ranges that include the last element of the array.

The point is how the pointer to one-past is obtained, not that its 
address is what it is.

That's the lunacy of the original C standard: to differentiate between 
the properties of two pointers that compare equal, based on how they 
were obtained.

Which means that you cannot formally well-behaved move a pointer to 
basic item through a multidimensional array, even though the array is 
guaranteed contiguous. If addresses were all that counted, you could.


> I'm puzzled how you could consider it a blunder to allow these things.
> The amount of code that would break if they were disallowed would be
> enormous.

You're puzzled because your claim about what I've said, is a nonsense 
view that I have not articulated.


- Alf

[toc] | [prev] | [next] | [standalone]


#82918

FromDavid Brown <david.brown@hesbynett.no>
Date2022-02-05 13:53 +0100
Message-ID<stls0p$jhf$1@dont-email.me>
In reply to#82909
On 05/02/2022 11:56, Alf P. Steinbach wrote:
> On 5 Feb 2022 05:05, James Kuyper wrote:
> 
> The point is how the pointer to one-past is obtained, not that its
> address is what it is.
> 
> That's the lunacy of the original C standard: to differentiate between
> the properties of two pointers that compare equal, based on how they
> were obtained.
> 
> Which means that you cannot formally well-behaved move a pointer to
> basic item through a multidimensional array, even though the array is
> guaranteed contiguous. If addresses were all that counted, you could.
> 
> 
>> I'm puzzled how you could consider it a blunder to allow these things.
>> The amount of code that would break if they were disallowed would be
>> enormous.
> 
> You're puzzled because your claim about what I've said, is a nonsense
> view that I have not articulated.
> 

Let me see if I can understand and re-express the difference here, and
then it will be easier to discuss whether or not the behaviour is
defined in C and/or C++.  I'm writing the code here in a way that is
clear, works as C and C++ (in all standards), and pasted into
<https://godbolt.org> if anyone wants to see the simple generated
assembly, look at compiler warnings, etc.


Obviously I expect to be corrected if this is not the point Alf was
getting at.




char r[20];

void foo1(void) {
    char *p = &r[20];
    p--;
    *p = 1;
}

void foo2(void) {
    char *p = (&r)[1];
    p--;
    *p = 1;
}



"foo1" is clearly allowed - you can make a pointer that is one past an
array, decrement it, and get to the last element in the array.  This
sort of thing is a common idiom.

In "foo2", we are taking a pointer the object "r" which is itself an
array of 20 char.  We are treating this pointer as the start of an array
of length 1 (and size 20 char), then forming (but not accessing) the
lvalue of one past the last element of this single-element array.  This
lvalue is also of type "array of 20 char".  So when we assign it to p,
it is converted to a pointer to its first element.

"foo2" is more complicated, and not nearly as clear.  In particular, it
relies on the validity of moving between rows in a two-dimensional array
- it requires that pointers within a two dimensional array be able to
run off the end of one row and directly onto the other end of the
neighbour row.

I've a memory of this being discussed before, either in c.l.c or
c.l.c++, but I don't remember the outcome.

[toc] | [prev] | [next] | [standalone]


#82919

From"Alf P. Steinbach" <alf.p.steinbach@gmail.com>
Date2022-02-05 14:12 +0100
Message-ID<stlt38$q7q$1@dont-email.me>
In reply to#82918
On 5 Feb 2022 13:53, David Brown wrote:
> On 05/02/2022 11:56, Alf P. Steinbach wrote:
>> On 5 Feb 2022 05:05, James Kuyper wrote:
>>
>> The point is how the pointer to one-past is obtained, not that its
>> address is what it is.
>>
>> That's the lunacy of the original C standard: to differentiate between
>> the properties of two pointers that compare equal, based on how they
>> were obtained.
>>
>> Which means that you cannot formally well-behaved move a pointer to
>> basic item through a multidimensional array, even though the array is
>> guaranteed contiguous. If addresses were all that counted, you could.
>>
>>
>>> I'm puzzled how you could consider it a blunder to allow these things.
>>> The amount of code that would break if they were disallowed would be
>>> enormous.
>>
>> You're puzzled because your claim about what I've said, is a nonsense
>> view that I have not articulated.
>>
> 
> Let me see if I can understand and re-express the difference here, and
> then it will be easier to discuss whether or not the behaviour is
> defined in C and/or C++.  I'm writing the code here in a way that is
> clear, works as C and C++ (in all standards), and pasted into
> <https://godbolt.org> if anyone wants to see the simple generated
> assembly, look at compiler warnings, etc.
> 
> 
> Obviously I expect to be corrected if this is not the point Alf was
> getting at.
> 
> 
> 
> 
> char r[20];
> 
> void foo1(void) {
>      char *p = &r[20];
>      p--;
>      *p = 1;
> }
> 
> void foo2(void) {
>      char *p = (&r)[1];
>      p--;
>      *p = 1;
> }
> 
> 
> 
> "foo1" is clearly allowed - you can make a pointer that is one past an
> array, decrement it, and get to the last element in the array.  This
> sort of thing is a common idiom.

Yep.


> In "foo2", we are taking a pointer the object "r" which is itself an
> array of 20 char.  We are treating this pointer as the start of an array
> of length 1 (and size 20 char), then forming (but not accessing) the
> lvalue of one past the last element of this single-element array.  This
> lvalue is also of type "array of 20 char".  So when we assign it to p,
> it is converted to a pointer to its first element.
> 
> "foo2" is more complicated, and not nearly as clear.  In particular, it
> relies on the validity of moving between rows in a two-dimensional array
> - it requires that pointers within a two dimensional array be able to
> run off the end of one row and directly onto the other end of the
> neighbour row.
> 
> I've a memory of this being discussed before, either in c.l.c or
> c.l.c++, but I don't remember the outcome.

Yep.

The outcome is that it's not formally valid. I remember because I argued 
strongly that it had to be valid, based on my notion that the C and C++ 
standards are (or were) practical. Then someone produced the C 
committee's rationale, or in my view, silly excuse and wrong decision...

- Alf

[toc] | [prev] | [next] | [standalone]


#82988

FromAnand Hariharan <mailto.anand.hariharan@gmail.com>
Date2022-02-12 11:13 -0800
Message-ID<35c223d5-0f11-4368-89d7-de986d7f5294n@googlegroups.com>
In reply to#82918
On Saturday, February 5, 2022 at 12:54:29 PM UTC, David Brown wrote:
>
[...] 
> char r[20]; 
> 
> void foo1(void) { 
> char *p = &r[20]; 
[...]
> 
> "foo1" is clearly allowed - you can make a pointer that is one past an 
> array
[...]

This is clearly in "Language Lawyer" territory, and IANAL.

To me x[y] is shorthand for *(x + y).  In other words, there is a dereference involved in x[y].

So if &r[20] is not UB, it is only because there is implicit reliance on compiler 'optimization' -- something to the effect of &*(r + 20) being simplified ('optimized') to (r + 20)

[toc] | [prev] | [next] | [standalone]


#82989

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-02-12 22:18 -0500
Message-ID<su9t9s$ig2$1@dont-email.me>
In reply to#82988
On 2/12/22 14:13, Anand Hariharan wrote:
> On Saturday, February 5, 2022 at 12:54:29 PM UTC, David Brown wrote:
>>
> [...] 
>> char r[20]; 
>>
>> void foo1(void) { 
>> char *p = &r[20]; 
> [...]
>>
>> "foo1" is clearly allowed - you can make a pointer that is one past an 
>> array
> [...]
> 
> This is clearly in "Language Lawyer" territory, and IANAL.
> 
> To me x[y] is shorthand for *(x + y).  In other words, there is a dereference involved in x[y].
> 
> So if &r[20] is not UB, it is only because there is implicit reliance on compiler 'optimization' -- something to the effect of &*(r + 20) being simplified ('optimized') to (r + 20)

If this were comp.lang.c, I'd have an easy response to that argument:
it's not a mere "optimization", it's explicitly mandated by the
standard. The following wording was first introduced in C99:

"The unary & operator yields the address of its operand. ... If the
operand is the result of a unary * operator, neither that operator nor
the & operator is evaluated and the result is as if both were omitted,
except that the constraints on the operators still apply and the result
is not an lvalue." (6.5.3.2p3).

Because of that clause, if there's no problem an expression E that has a
pointer type, and if &*E violates no constraints, then there's also no
problem with &*E, which has the same value, even if *E would have had
undefined behavior (for instance, if the value of E is a null pointer or
(as in this case) points one past the end of an array.

I don't know why the C++ committee never choose to add similar wording
to the C++ standard.

[toc] | [prev] | [next] | [standalone]


#82993

FromRichard Damon <Richard@Damon-Family.org>
Date2022-02-13 12:51 -0500
Message-ID<9ybOJ.98566$Rza5.53467@fx47.iad>
In reply to#82989
On 2/12/22 10:18 PM, James Kuyper wrote:
> On 2/12/22 14:13, Anand Hariharan wrote:
>> On Saturday, February 5, 2022 at 12:54:29 PM UTC, David Brown wrote:
>>>
>> [...]
>>> char r[20];
>>>
>>> void foo1(void) {
>>> char *p = &r[20];
>> [...]
>>>
>>> "foo1" is clearly allowed - you can make a pointer that is one past an
>>> array
>> [...]
>>
>> This is clearly in "Language Lawyer" territory, and IANAL.
>>
>> To me x[y] is shorthand for *(x + y).  In other words, there is a dereference involved in x[y].
>>
>> So if &r[20] is not UB, it is only because there is implicit reliance on compiler 'optimization' -- something to the effect of &*(r + 20) being simplified ('optimized') to (r + 20)
> 
> If this were comp.lang.c, I'd have an easy response to that argument:
> it's not a mere "optimization", it's explicitly mandated by the
> standard. The following wording was first introduced in C99:
> 
> "The unary & operator yields the address of its operand. ... If the
> operand is the result of a unary * operator, neither that operator nor
> the & operator is evaluated and the result is as if both were omitted,
> except that the constraints on the operators still apply and the result
> is not an lvalue." (6.5.3.2p3).
> 
> Because of that clause, if there's no problem an expression E that has a
> pointer type, and if &*E violates no constraints, then there's also no
> problem with &*E, which has the same value, even if *E would have had
> undefined behavior (for instance, if the value of E is a null pointer or
> (as in this case) points one past the end of an array.
> 
> I don't know why the C++ committee never choose to add similar wording
> to the C++ standard.

I think because it would only apply for the default operator *() and 
operator &(), and if these operators exist for the given type, they WILL 
be called, and not optimized away.

This can happen particularly with smart pointers.

[toc] | [prev] | [next] | [standalone]


#82994

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2022-02-13 20:16 +0200
Message-ID<subhtm$42r$1@dont-email.me>
In reply to#82989
13.02.2022 05:18 James Kuyper kirjutas:
> On 2/12/22 14:13, Anand Hariharan wrote:
>> On Saturday, February 5, 2022 at 12:54:29 PM UTC, David Brown wrote:
>>>
>> [...]
>>> char r[20];
>>>
>>> void foo1(void) {
>>> char *p = &r[20];
>> [...]
>>>
>>> "foo1" is clearly allowed - you can make a pointer that is one past an
>>> array
>> [...]
>>
>> This is clearly in "Language Lawyer" territory, and IANAL.
>>
>> To me x[y] is shorthand for *(x + y).  In other words, there is a dereference involved in x[y].
>>
>> So if &r[20] is not UB, it is only because there is implicit reliance on compiler 'optimization' -- something to the effect of &*(r + 20) being simplified ('optimized') to (r + 20)
> 
> If this were comp.lang.c, I'd have an easy response to that argument:
> it's not a mere "optimization", it's explicitly mandated by the
> standard. The following wording was first introduced in C99:
> 
> "The unary & operator yields the address of its operand. ... If the
> operand is the result of a unary * operator, neither that operator nor
> the & operator is evaluated and the result is as if both were omitted,
> except that the constraints on the operators still apply and the result
> is not an lvalue." (6.5.3.2p3).
> 
> Because of that clause, if there's no problem an expression E that has a
> pointer type, and if &*E violates no constraints, then there's also no
> problem with &*E, which has the same value, even if *E would have had
> undefined behavior (for instance, if the value of E is a null pointer or
> (as in this case) points one past the end of an array.
> 
> I don't know why the C++ committee never choose to add similar wording
> to the C++ standard.

One reason might be that this wording would prohibit debugging 
implementations of operator[] which check its arguments and fail if it
is >=N.

Such an instrumented operator[] would not have a way to know if its 
result is immediately passed to the & operator or not, so it cannot take 
this into an account. For a compiler implementer it would be easier to 
take into account, so e.g. the gcc bounds-checking regime would still be 
possible to implement, but an ordinary user-defined bounds-checking 
operator[] would not be possible.

So I would say the difference of C and C++ in this aspect is because in 
C++ one can redefine operator[], but not in C.

[toc] | [prev] | [next] | [standalone]


Page 1 of 6  [1] 2 3 4 5 6  Next page →

Back to top | Article view | comp.lang.c++


csiph-web