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 4 of 6 — ← Prev page 1 2 3 [4] 5 6 Next page →
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2022-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]
| From | "Alf P. Steinbach" <alf.p.steinbach@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2022-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]
| From | "Alf P. Steinbach" <alf.p.steinbach@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Muttley@dastardlyhq.com |
|---|---|
| Date | 2022-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]
| From | "Alf P. Steinbach" <alf.p.steinbach@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Muttley@dastardlyhq.com |
|---|---|
| Date | 2022-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]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2022-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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2022-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]
| From | "Alf P. Steinbach" <alf.p.steinbach@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2022-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2022-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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2022-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2022-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2022-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]
| From | red floyd <no.spam.here@its.invalid> |
|---|---|
| Date | 2022-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