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 4 of 6 — ← Prev page 1 2 3 [4] 5 6  Next page →


#83002

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-02-15 00:10 -0800
Message-ID<86zgmsh7nh.fsf@linuxsc.com>
In reply to#82983
"Alf P. Steinbach" <alf.p.steinbach@gmail.com> writes:

> On 11 Feb 2022 14:41, Tim Rentsch wrote:
>
>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>
>>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>>
>>>> Rather than thinking about pointer values, it might help to start
>>>> with objects.  [..illustrative examples..]
>>>>
>>>> Casting a pointer to a different type doesn't change what objects
>>>> it can access.  At least, this rule holds in C, [...]
>>>
>>> Really the only issue I had is resolved by the rule that "the array" is
>>> always the smallest enclosing array that contains the thing pointed to
>>> (before any conversions of course).
>>
>> Interesting.  I hadn't thought of it that way before.  Seems right.
>>
>> I should make a clarifying statement about casting not changing
>> what objects can be accessed.  If we have this code fragment
>>
>>      int foo[10][20];
>>      extern void set_elements( int *, size_t, int )
>>
>>      set_elements( (int*) &foo, 10*20, -1 );
>>
>> an argument could be made that set_elements() cannot use pointer
>> arithmetic (including that implied by use of []) on its first
>> argument other than to access between foo[0][0] and foo[0][19] (or
>> to construct a pointer to foo[0][20]).  The reasoning would be that
>> there is no array of 200 elements, so the conditions for address
>> arithmetic would not be met for index values other than between 0 and
>> 20, and so would technically be undefined behavior.
>
> First, for C++20 the above `reinterpret_cast`-expressed-as-C-cast
> suffers from not involving "interconvertible" pointers, as noted in
> 6.8.2/4.4:
>
> "An array object and its first element are not
> pointer-interconvertible, even though they have the same address."

Amusing.  The language guarantees that the addresses line up, and
then says the cast isn't guaranteed to work (apparently that is a
change since C++14) even though it obviously will.  Too funny for
words.

> Formally notes are not part of the formal language specification,
> they're not "normative".  [...]

It seems clear that what the "Note" says follows from other
normative text.

> [...]
>
>>  It would be
>> surprising if that putative undefined behavior would result in the
>> code "doing the wrong thing", but I feel obliged to point out the
>> possible alternative reading nonetheless.
>>
>> Even if the reading proposed above holds, set_elements() can be
>> written in a way that avoids the putative undefined behavior:
>>
>>      void
>>      set_elements( int *v, size_t n, int value ){
>>          while(  n-- > 0  ){
>>              *(int*)( (char*)v + n * sizeof *v ) = value;
>>          }
>>      }
>>
>> This code has to work for the call that passes '(int*)&foo',
>> because all objects have an implied character array that overlays
>> the entire object, which is all of foo in this case.
>
> Again, for C++ (though I understand you're discussing the C case)
> you're colliding with a formal brick wall.
>
> The general consensus is that only `memcpy` plus one more mechanism I
> don't recall now (citing lack of coffee plus excessive blood sugar
> etc.) is sufficiently formally supported to avoid formal UB for
> copying bytes of objects.

There is no copying of bytes in the above code.

> In particular a `reinterpret_cast`, in the above code expressed as a C
> style cast, is a good way to let loose the strict aliasing demons of
> the g++ compiler.  [...]

In the context the above code is used, there are no violations of
type-based aliasing rules.  Hence no "strict aliasing demons".

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


#83003

From"Alf P. Steinbach" <alf.p.steinbach@gmail.com>
Date2022-02-15 20:58 +0100
Message-ID<suh0kq$pna$1@dont-email.me>
In reply to#83002
On 15 Feb 2022 09:10, Tim Rentsch wrote:
> "Alf P. Steinbach" <alf.p.steinbach@gmail.com> writes:
>> On 11 Feb 2022 14:41, Tim Rentsch wrote:
>>
>>> [snip]
>>> Even if the reading proposed above holds, set_elements() can be
>>> written in a way that avoids the putative undefined behavior:
>>>
>>>       void
>>>       set_elements( int *v, size_t n, int value ){
>>>           while(  n-- > 0  ){
>>>               *(int*)( (char*)v + n * sizeof *v ) = value;
>>>           }
>>>       }
>>>
>>> This code has to work for the call that passes '(int*)&foo',
>>> because all objects have an implied character array that overlays
>>> the entire object, which is all of foo in this case.
>>
>> Again, for C++ (though I understand you're discussing the C case)
>> you're colliding with a formal brick wall.
>>
>> The general consensus is that only `memcpy` plus one more mechanism I
>> don't recall now (citing lack of coffee plus excessive blood sugar
>> etc.) is sufficiently formally supported to avoid formal UB for
>> copying bytes of objects.
> 
> There is no copying of bytes in the above code.
> 
>> In particular a `reinterpret_cast`, in the above code expressed as a C
>> style cast, is a good way to let loose the strict aliasing demons of
>> the g++ compiler.  [...]
> 
> In the context the above code is used, there are no violations of
> type-based aliasing rules.  Hence no "strict aliasing demons".

The C style `(int*)` expresses a C++ `reinterpret_cast<int*>` of a `char*`.

It doesn't matter for the formal that, taking into account how that 
`char*` is produced, both we and any reasonable compiler know that the 
addresses that result are the addresses of items in an `int` array.

The byte copying you failed to see ("no copying of bytes") while 
referring to it ("character array that overlays") is the copying of the 
bytes of `value` to each array item

However, getting rid of that local UB is even easier then using `memcpy` 
instead of `reinterpret_cast`: just use indexing of `v`.

The outer context UB due to how the pointer to first item was obtained, 
is more problematic. Think about `v` in that code as a fat pointer that 
contains first accessible address, one beyond last accessible address, 
and the ordinary pointer value, and where any pointer arithmetic or 
casting preserves the limits. Then (hopefully) you'll see that such 
shenanigans don't help, that a sufficiently type safe implementation can 
foil any effort, which IMHO is of negative value in modern programming.

- Alf

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


#83005

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-02-16 06:40 +0000
Message-ID<sui695$g3k$1@gioia.aioe.org>
In reply to#83003
Alf P. Steinbach <alf.p.steinbach@gmail.com> wrote:
> The C style `(int*)` expresses a C++ `reinterpret_cast<int*>` of a `char*`.

The C style cast is not identical to a reinterpret_cast in every possible
way, though. Most particularly, reinterpret_cast cannot be used to cast
away the constness of a pointer. (The C style cast can.)

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


#83008

From"Alf P. Steinbach" <alf.p.steinbach@gmail.com>
Date2022-02-16 09:54 +0100
Message-ID<suie4j$1np$1@dont-email.me>
In reply to#83005
On 16 Feb 2022 07:40, Juha Nieminen wrote:
> Alf P. Steinbach <alf.p.steinbach@gmail.com> wrote:
>> The C style `(int*)` expresses a C++ `reinterpret_cast<int*>` of a `char*`.
> 
> The C style cast is not identical to a reinterpret_cast in every possible
> way, though. Most particularly, reinterpret_cast cannot be used to cast
> away the constness of a pointer. (The C style cast can.)

It was about the concrete cast in Tim's code.

The C style cast in C++ can do a `const_cast`, a `static_cast`, a 
`reinterpret_cast` (I believe at most 2 of these at a time) plus a cast 
to inaccessible base class, where it's the only way to express that.


- Alf

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


#83009

FromMuttley@dastardlyhq.com
Date2022-02-16 09:00 +0000
Message-ID<suieg4$1ldo$1@gioia.aioe.org>
In reply to#83008
On Wed, 16 Feb 2022 09:54:43 +0100
"Alf P. Steinbach" <alf.p.steinbach@gmail.com> wrote:
>On 16 Feb 2022 07:40, Juha Nieminen wrote:
>> Alf P. Steinbach <alf.p.steinbach@gmail.com> wrote:
>>> The C style `(int*)` expresses a C++ `reinterpret_cast<int*>` of a `char*`.
>> 
>> The C style cast is not identical to a reinterpret_cast in every possible
>> way, though. Most particularly, reinterpret_cast cannot be used to cast
>> away the constness of a pointer. (The C style cast can.)
>
>It was about the concrete cast in Tim's code.
>
>The C style cast in C++ can do a `const_cast`, a `static_cast`, a 
>`reinterpret_cast` (I believe at most 2 of these at a time) plus a cast 
>to inaccessible base class, where it's the only way to express that.

Which is why a lot of C++ devs still use C style casting, aside from the
fact that its less verbose and looks neater.

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


#83011

From"Alf P. Steinbach" <alf.p.steinbach@gmail.com>
Date2022-02-16 20:25 +0100
Message-ID<sujj2f$igs$1@dont-email.me>
In reply to#83009
On 16 Feb 2022 10:00, Muttley@dastardlyhq.com wrote:
> On Wed, 16 Feb 2022 09:54:43 +0100
> "Alf P. Steinbach" <alf.p.steinbach@gmail.com> wrote:
>> On 16 Feb 2022 07:40, Juha Nieminen wrote:
>>> Alf P. Steinbach <alf.p.steinbach@gmail.com> wrote:
>>>> The C style `(int*)` expresses a C++ `reinterpret_cast<int*>` of a `char*`.
>>>
>>> The C style cast is not identical to a reinterpret_cast in every possible
>>> way, though. Most particularly, reinterpret_cast cannot be used to cast
>>> away the constness of a pointer. (The C style cast can.)
>>
>> It was about the concrete cast in Tim's code.
>>
>> The C style cast in C++ can do a `const_cast`, a `static_cast`, a
>> `reinterpret_cast` (I believe at most 2 of these at a time) plus a cast
>> to inaccessible base class, where it's the only way to express that.
> 
> Which is why a lot of C++ devs still use C style casting, aside from the
> fact that its less verbose and looks neater.

Usually this abundance of possible meanings is mentioned as a main 
reason to avoid C style casts (except that the cast to inaccessible base 
can't avoid C syntax, since it's the only available syntax), because the 
meaning can easily inadvertently change with maintenance of the code.

Ditto for the "looks neater": the C++ named casts are verbose precisely 
to not be very attractive, so as to avoid their habitual use.

So I guess the "which is why" is at least arguable. :-o


- Alf

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


#83016

FromMuttley@dastardlyhq.com
Date2022-02-17 08:53 +0000
Message-ID<sul2e2$1cd8$1@gioia.aioe.org>
In reply to#83011
On Wed, 16 Feb 2022 20:25:01 +0100
"Alf P. Steinbach" <alf.p.steinbach@gmail.com> wrote:
>On 16 Feb 2022 10:00, Muttley@dastardlyhq.com wrote:
>> On Wed, 16 Feb 2022 09:54:43 +0100
>> "Alf P. Steinbach" <alf.p.steinbach@gmail.com> wrote:
>>> On 16 Feb 2022 07:40, Juha Nieminen wrote:
>>>> Alf P. Steinbach <alf.p.steinbach@gmail.com> wrote:
>>>>> The C style `(int*)` expresses a C++ `reinterpret_cast<int*>` of a
>`char*`.
>>>>
>>>> The C style cast is not identical to a reinterpret_cast in every possible
>>>> way, though. Most particularly, reinterpret_cast cannot be used to cast
>>>> away the constness of a pointer. (The C style cast can.)
>>>
>>> It was about the concrete cast in Tim's code.
>>>
>>> The C style cast in C++ can do a `const_cast`, a `static_cast`, a
>>> `reinterpret_cast` (I believe at most 2 of these at a time) plus a cast
>>> to inaccessible base class, where it's the only way to express that.
>> 
>> Which is why a lot of C++ devs still use C style casting, aside from the
>> fact that its less verbose and looks neater.
>
>Usually this abundance of possible meanings is mentioned as a main 
>reason to avoid C style casts (except that the cast to inaccessible base 
>can't avoid C syntax, since it's the only available syntax), because the 
>meaning can easily inadvertently change with maintenance of the code.
>
>Ditto for the "looks neater": the C++ named casts are verbose precisely 

Verbose and in the case of const_cast , illogical. It should be called
unconst_cast or removeconst_cast. Also static_cast is a strange name IMO.
Why static? Why not type_cast or similar?

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


#83018

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2022-02-17 16:11 +0200
Message-ID<sull24$ami$1@dont-email.me>
In reply to#83016
17.02.2022 10:53 Muttley@dastardlyhq.com kirjutas:
>>
>> Ditto for the "looks neater": the C++ named casts are verbose precisely
> 
> Verbose and in the case of const_cast , illogical. It should be called
> unconst_cast or removeconst_cast. Also static_cast is a strange name IMO.
> Why static? Why not type_cast or similar?

const_cast can also add const. This might be useful for selecting the 
needed overload.

The name const_cast just means a cast which can add or remove the const 
qualifier, I see nothing illogical here.

static_cast is named in contrast to dynamic_cast and means it's a 
compile-time feature which does not cause any wasted cycles at run time. 
Calling it type_cast would be misleading because dynamic_cast is also a 
type cast (and much more versatile).

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


#83019

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-02-17 10:58 -0500
Message-ID<sulrbq$fca$1@dont-email.me>
In reply to#83016
On 2/17/22 03:53, Muttley@dastardlyhq.com wrote:
> On Wed, 16 Feb 2022 20:25:01 +0100
> "Alf P. Steinbach" <alf.p.steinbach@gmail.com> wrote:
...
>> Ditto for the "looks neater": the C++ named casts are verbose precisely 
>
> Verbose ...

That's deliberate. It's meant to discourage unnecessary casts, and to
make it easier to search for necessary ones. Most casts are unnecessary
because they specify a conversion that would happen implicitly even
without the cast. Those that are necessary are, as a matter of
deliberate design, the dangerous ones. They therefore deserve close
attention. It can be difficult to give them the attention they need if
there's too many of them, or if they're too hard to find.

> ... and in the case of const_cast , illogical.

Agreed - it should be qual_cast<>, since it can be used to either add or
remove `volatile` as well as 'const'.

It should be called
> unconst_cast or removeconst_cast. ...

Bad idea - people would get the mistaken idea that it could only be used
to remove `const`.

> ... Also static_cast is a strange name IMO.
> Why static? ...

Because it can be resolved statically, at compile-time, rather than
dynamically, like dynamic_cast<>.

> ... Why not type_cast or similar?

Calling any individual cast a type_cast<> would give the mistaken
impression that the other casts don't change the type.

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


#83015

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-02-17 07:32 +0000
Message-ID<suktm8$1c2a$1@gioia.aioe.org>
In reply to#83009
Muttley@dastardlyhq.com wrote:
> Which is why a lot of C++ devs still use C style casting, aside from the
> fact that its less verbose and looks neater.

The problem with the C style casting is that it's "too powerful" and can
more easily lead to mistakes and bugs, when accidentally doing a cast that
shouldn't be done.

The C++ style casts express intent better. If you use static_cast, you are
explicitly asking the compiler to do a cast between compatible types, and
thus the possibility of mistakes is lessened. If you made a mistake and
tried to cast between incompatible types, you get a compiler error, showing
you your mistake immediately (rather than you having to find out at runtime,
and then having to debug the program. And that's assuming you happen to
run that particular piece of code.)

The code also becomes clearer and more "self-documenting" with the C++
style casts. You can see at a glance what kind of casts are being done,
and that they are intentional. When you see "reinterpret_cast" you see
that the programmer actually intended to cast between incompatible
types there, and that it wasn't just an oversight and mistake.

Some projects out there even go so far as to *disable* C style
casting (compilers often provide a flag for this) as well as requiring
explicit casts for some conversions (such as from signed to unsigned
types), which increases code clarity and lessens the chances of making
mistakes.

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


#83636

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-04-19 02:21 -0700
Message-ID<86wnfl8m3u.fsf@linuxsc.com>
In reply to#83003
"Alf P. Steinbach" <alf.p.steinbach@gmail.com> writes:

> On 15 Feb 2022 09:10, Tim Rentsch wrote:
>
>> "Alf P. Steinbach" <alf.p.steinbach@gmail.com> writes:
>>
>>> On 11 Feb 2022 14:41, Tim Rentsch wrote:
>>>
>>>> [snip]
>>>> Even if the reading proposed above holds, set_elements() can be
>>>> written in a way that avoids the putative undefined behavior:
>>>>
>>>>       void
>>>>       set_elements( int *v, size_t n, int value ){
>>>>           while(  n-- > 0  ){
>>>>               *(int*)( (char*)v + n * sizeof *v ) = value;
>>>>           }
>>>>       }
>>>>
>>>> This code has to work for the call that passes '(int*)&foo',
>>>> because all objects have an implied character array that overlays
>>>> the entire object, which is all of foo in this case.
>>>
>>> Again, for C++ (though I understand you're discussing the C case)
>>> you're colliding with a formal brick wall.
>>>
>>> The general consensus is that only `memcpy` plus one more mechanism I
>>> don't recall now (citing lack of coffee plus excessive blood sugar
>>> etc.) is sufficiently formally supported to avoid formal UB for
>>> copying bytes of objects.
>>
>> There is no copying of bytes in the above code.
>>
>>> In particular a `reinterpret_cast`, in the above code expressed as a C
>>> style cast, is a good way to let loose the strict aliasing demons of
>>> the g++ compiler.  [...]
>>
>> In the context the above code is used, there are no violations of
>> type-based aliasing rules.  Hence no "strict aliasing demons".
>
> The C style `(int*)` expresses a C++ `reinterpret_cast<int*>` of a
> `char*`.
>
> It doesn't matter for the formal that, taking into account how
> that char*` is produced, both we and any reasonable compiler know
> that the addresses that result are the addresses of items in an
> `int` array.
>
> The byte copying you failed to see ("no copying of bytes") while
> referring to it ("character array that overlays") is the copying
> of the bytes of `value` to each array item

Look again.  The code shown performs no accesses of any kind through
any character array.  Hence there is no copying of bytes in the
above code.

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


#83637

From"Alf P. Steinbach" <alf.p.steinbach@gmail.com>
Date2022-04-19 11:56 +0200
Message-ID<t3m11c$9i3$1@dont-email.me>
In reply to#83636
On 19 Apr 2022 11:21, Tim Rentsch wrote:
> "Alf P. Steinbach" <alf.p.steinbach@gmail.com> writes:
>>
>> The byte copying you failed to see ("no copying of bytes") while
>> referring to it ("character array that overlays") is the copying
>> of the bytes of `value` to each array item
> 
> Look again.  The code shown performs no accesses of any kind through
> any character array.  Hence there is no copying of bytes in the
> above code.

How does one deal with irrational blind denial in an online discussion?

- Alf

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


#83710

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-04-25 03:02 -0700
Message-ID<86sfq18oqp.fsf@linuxsc.com>
In reply to#83637
"Alf P. Steinbach" <alf.p.steinbach@gmail.com> writes:

> On 19 Apr 2022 11:21, Tim Rentsch wrote:
>
>> "Alf P. Steinbach" <alf.p.steinbach@gmail.com> writes:
>>
>>> The byte copying you failed to see ("no copying of bytes") while
>>> referring to it ("character array that overlays") is the copying
>>> of the bytes of `value` to each array item
>>
>> Look again.  The code shown performs no accesses of any kind through
>> any character array.  Hence there is no copying of bytes in the
>> above code.
>
> How does one deal with irrational blind denial in an online discussion?

If you want to show that there is copying of bytes, simply point
out the expression in the code that reads or writes an object
using a character type.  If there is no such expression then
there is no copying of bytes (with the usual qualifiers about
memcpy(), etc).

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


#82987

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2022-02-12 00:01 +0000
Message-ID<87mtixj6mb.fsf@bsb.me.uk>
In reply to#82982
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>
>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>
>>> Rather than thinking about pointer values, it might help to start
>>> with objects.  [..illustrative examples..]
>>>
>>> Casting a pointer to a different type doesn't change what objects
>>> it can access.  At least, this rule holds in C, [...]
>
>> Really the only issue I had is resolved by the rule that "the array" is
>> always the smallest enclosing array that contains the thing pointed to
>> (before any conversions of course).
>
> Interesting.  I hadn't thought of it that way before.  Seems right.
>
> I should make a clarifying statement about casting not changing
> what objects can be accessed.

But it does change the n used by the standard for explaining what
pointers can be validly constructed.

> If we have this code fragment
>
>     int foo[10][20];

To borrow this declaration, &foo points to the whole array which has to
be treated as the sole element in an array of length one so n is 1 here.
All we can do with this pointer is add one to it (but we must not then
dereference it).  Add a cast, (int *)&foo, and n is not 1 anymore,
though I can't tell from your remarks if you think it's 20 or 40.

>     extern void set_elements( int *, size_t, int )
>
>     set_elements( (int*) &foo, 10*20, -1 );
>
> an argument could be made that set_elements() cannot use pointer
> arithmetic (including that implied by use of []) on its first
> argument other than to access between foo[0][0] and foo[0][19] (or
> to construct a pointer to foo[0][20]).  The reasoning would be that
> there is no array of 200 elements, so the conditions for address
> arithmetic would not be met for index values other than between 0 and
> 20, and so would technically be undefined behavior.  It would be
> surprising if that putative undefined behavior would result in the
> code "doing the wrong thing", but I feel obliged to point out the
> possible alternative reading nonetheless.
>
> Even if the reading proposed above holds, set_elements() can be
> written in a way that avoids the putative undefined behavior:
>
>     void
>     set_elements( int *v, size_t n, int value ){
>         while(  n-- > 0  ){
>             *(int*)( (char*)v + n * sizeof *v ) = value;
>         }
>     }
>
> This code has to work for the call that passes '(int*)&foo',
> because all objects have an implied character array that overlays
> the entire object, which is all of foo in this case.

As you say, this code has special dispensation.  That's why I switched
from char arrays to int ones!  It's what direct additions and
subtractions are permitted for any given pointer that I no longer feel
sure about.  Your "a case could be made" suggests you are not entirely
sure either, though it does suggest you consider that case is a stretch.

-- 
Ben.

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


#83001

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-02-14 23:55 -0800
Message-ID<864k50imxm.fsf@linuxsc.com>
In reply to#82987
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:

[edited for brevity]

>> If we have this code fragment
>>
>>     int foo[10][20];
>>     extern void set_elements( int *, size_t, int )
>>
>>     set_elements( (int*) &foo, 10*20, -1 );
>>
>> an argument could be made that set_elements() cannot use pointer
>> arithmetic (including that implied by use of []) on its first
>> argument other than to access between foo[0][0] and foo[0][19] (or
>> to construct a pointer to foo[0][20]).  [...]
>
> [...] It's what direct additions and subtractions are permitted
> for any given pointer that I no longer feel sure about.  Your "a
> case could be made" suggests you are not entirely sure either,
> though it does suggest you consider that case is a stretch.

The implied question here has a somewhat longish answer.  I'll
get to it when I can.  Also, as it seems we have drifted rather
far from C++, comp.std.c is I think a better place to continue.

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


#82960

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-02-07 18:31 +0100
Message-ID<strl1r$th7$2@dont-email.me>
In reply to#82944
Am 06.02.2022 um 22:53 schrieb Ben Bacarisse:


>> References:  section 6.5.6 paragraph 8 for C (n1570);
>> section 7.6.6 paragraph 4.2 for C++ (N4860).

> So given
> 
>    int i;
>    char *cp = (void *)(&i + 1);
> 
> accessing the bytes of i from cp is also undefined. ...

Idiot ...

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


#82961

Fromscott@slp53.sl.home (Scott Lurndal)
Date2022-02-07 17:43 +0000
Message-ID<KScMJ.10756$r6p7.1033@fx41.iad>
In reply to#82960
Bonita Montero <Bonita.Montero@gmail.com> writes:
>Am 06.02.2022 um 22:53 schrieb Ben Bacarisse:
>
>
>>> References:  section 6.5.6 paragraph 8 for C (n1570);
>>> section 7.6.6 paragraph 4.2 for C++ (N4860).
>
>> So given
>> 
>>    int i;
>>    char *cp = (void *)(&i + 1);
>> 
>> accessing the bytes of i from cp is also undefined. ...
>
>Idiot ...

 Self-descriptive terminology from someone who can't tell
his little end from his big end.

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


#82943

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-02-06 14:25 -0500
Message-ID<stp7be$soo$1@dont-email.me>
In reply to#82940
On 2/6/22 09:35, Ben Bacarisse wrote:
> "Alf P. Steinbach" <alf.p.steinbach@gmail.com> writes:
>
>> The code using `(&result)[1]` involves a couple of extra conversions
>
> Eh? char *ep = r + sizeof(r); involves one array-to-pointer conversion
> just as char *ep = (&r)[1]; does.
>
>> and indirections and is thus needlessly complex, plus it's formally
>> UB,
> > Can you point to where this is made UB in the C++ standard?

The original code contained the following line:

> char result[28], *ep = (&result)[1];

"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 and an object of type T that is not an array
element is considered to belong to an array with one element of type T."
(6.8.2p3)

&result has the type char (*)[20], and is therefore treated as pointing
at the first and only element of an array of char[20]. (&result)[1] is
defined as equivalent to *(&result + 1), and the result of that addition
is a pointer that points at the purely hypothetical second element of
that array. In principle, that expression dereferences a hypothetical
object, which would be a problem. But the result of that dereference has
array type, and is therefore implicitly converted to a pointer to the
first element of that array. I think it is debatable whether that
expression is problematic, my own feeling is that it isn't.

It's a later step in the same routine that makes the behavior
unambiguously undefined:

> ep -= 4;


"if P points to an array element i of an array object x with n elements
(9.3.3.4), 76 ... 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)

In this case i==0, j==4, and n==20, The specified condition is not met,
so the behavior is undefined.

Since the C rules are part of this discussion, it should be noted that
the C standard doesn't use the concept of a "hypothetical element" one
past the end of the array. Instead, clause 6.5.6p9 of the C standard,
which corresponds 7.6.6p4 from the C++ standard cited above, is more
complicated by reason of having special wording for pointers "one past
the end of the array". However, taking that difference into
consideration, they say the same things about violating the bounds of an
array.

There's one other difference between the C and C++ standards: back in
the days of C90, when the issue came up of what that clause meant for
multidimensional arrays, some people claimed that an array declared as
`int a[4][5]` should be treated as an array of 20 ints for this purpose.
As a result a[1] gets implicitly converted to a pointer to the 6th
element of that 20 element array, and a[1][7] is therefore a legal way
of referring to the 13th element of that array, which can also be
referred to as a[2][2]. The C committee rejected that interpretation:
a[1] converts to a pointer that points at the first element of a 5
element array of int, and it's that 5-element array that determines how
much you can legally add or subtract from that pointer. To clarify that
point in future standards, they added the following item to C99 in
section J.2 "Undefined behavior":

"An array subscript is out of range, even if an object is apparently
accessible with the given subscript (as in the lvalue expression a[1][7]
given the declaration int a[4][5]) (6.5.6)"

Note that this wording was added to C99 without any corresponding change
to the wording of 6.5.6. That section did have changes, but none that
are relevant to the validity of a[1][7] in this context. They did this
because they felt that no change was needed, the existing wording
already made that point clear. There's no such wording in the C++ standard.

However, if the C committee was correct on that point, the same should
be true of C++, because despite the many differences between the two
standards, none of those differences affect the validity of a[1][7]. If
it's invalid in C, it should also be invalid in C++, and that is indeed
how I understand 7.6.6p4.

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


#82930

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-02-06 02:01 -0800
Message-ID<861r0gl3e3.fsf@linuxsc.com>
In reply to#82928
Bonita Montero <Bonita.Montero@gmail.com> writes:

> Am 06.02.2022 um 01:42 schrieb red floyd:
>
>> On 2/5/2022 10:51 AM, Bonita Montero wrote:
>>
>>>> On 2/4/2022 11:53 PM, Tim Rentsch wrote:
>>>>
>>>>>  char *ep = (&result)[1];
>>>>
>>>> Am 05.02.2022 um 19:10 schrieb red floyd:
>>>> Why the oddly unreadable initialization of ep?  Why not just
>>>>
>>>>  char *ep = result + sizeof(result)?
>>>
>>> I also consider (&result)[1] as the more elegant way.
>>
>> To be honest, I don't give a damn about your opinion.
>
> Your solution works only with char-arrays.
> Tims solution works with all arrays.

I don't claim any credit for this idiom.  I first learned the
idiom some time ago from a posting by Ben Bacarisse, and my
posting upthread here was simply copying the usage from his
earlier posting (which was in fact the posting to which I was
responding).

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


#82947

Fromred floyd <no.spam.here@its.invalid>
Date2022-02-06 19:37 -0800
Message-ID<stq46e$7su$1@redfloyd.dont-email.me>
In reply to#82928
On 2/6/2022 12:57 AM, Bonita Montero wrote:
> Am 06.02.2022 um 01:42 schrieb red floyd:
>> On 2/5/2022 10:51 AM, Bonita Montero wrote:
>>>> On 2/4/2022 11:53 PM, Tim Rentsch wrote:
>>>>>          char *ep = (&result)[1];
>>>
>>>  > Am 05.02.2022 um 19:10 schrieb red floyd:
>>>> Why the oddly unreadable initialization of ep?   Why not just
>>>>
>>>>      char *ep = result + sizeof(result)?
>>>>
>>>
>>> I also consider (&result)[1] as the more elegant way.
>>
>> To be honest, I don't give a damn about your opinion.
> 
> Your solution works only with char-arrays.
> Tims solution works with all arrays.
> Therefore it's preferrable.
> 
>> Mine makes it explicitly clear what is going on, without
>> the whole weird casting shit.
> 

C++ should define

template<typename T, size_t N>
constexpr size_t array_size(T(&)[N]) { return N; }

Then the expression I wrote could be

char *ep = result + array_size(result);

or for an int

int arr[20];
int *ip = arr + array_size(arr);

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


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

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


csiph-web