Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #82895 > unrolled thread
| Started by | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| First post | 2022-02-04 13:54 +0100 |
| Last post | 2022-02-07 18:30 +0100 |
| Articles | 20 on this page of 103 — 18 participants |
Back to article view | Back to comp.lang.c++
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 →
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-02-04 13:54 +0100 |
| Subject | C++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]
| From | Muttley@dastardlyhq.com |
|---|---|
| Date | 2022-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Muttley@dastardlyhq.com |
|---|---|
| Date | 2022-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Muttley@dastardlyhq.com |
|---|---|
| Date | 2022-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Muttley@dastardlyhq.com |
|---|---|
| Date | 2022-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2022-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-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]
| From | "Alf P. Steinbach" <alf.p.steinbach@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2022-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-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]
| From | "Alf P. Steinbach" <alf.p.steinbach@gmail.com> |
|---|---|
| Date | 2022-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2022-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]
| From | "Alf P. Steinbach" <alf.p.steinbach@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Anand Hariharan <mailto.anand.hariharan@gmail.com> |
|---|---|
| Date | 2022-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2022-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]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-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