Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c++
Subject: Re: C++20 concepts rocks
Date: Mon, 07 Feb 2022 06:26:44 -0800
Organization: A noiseless patient Spider
Lines: 60
Message-ID: <8635kukb17.fsf@linuxsc.com>
References: <87k0easj5d.fsf@bsb.me.uk> <865yptlpgf.fsf@linuxsc.com> <87mtj4qd0h.fsf@bsb.me.uk> <86fsovkdjw.fsf@linuxsc.com> <877da7r7ap.fsf@bsb.me.uk> <86bkzjjs3c.fsf@linuxsc.com> <87k0e6q4j8.fsf@bsb.me.uk>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="792c2a82c28252afd7e8a94f82466189"; logging-data="9726"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19Mo8hqSW7n9HZ4Mvg9UUZCNWs3llyfHIw="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:Sg0+R9P9/e7sxyzj3OW8wxgAz1w= sha1:xBFbv8T7tGLNQugAjBPHM+jhpq4=
Xref: csiph.com comp.lang.c++:82955
Ben Bacarisse writes:
> Tim Rentsch writes:
>
>> Ben Bacarisse writes:
[.. considering the idiom (&x)[1], where x is an array ..]
>>> So given
>>>
>>> int i;
>>> char *cp = (void *)(&i + 1);
>>>
>>> accessing the bytes of i from cp is also undefined.
>>
>> No, accessing cp[-1], etc, is defined behavior. The two
>> situations are not analogous. The reason is that in this case
>> there is only one array, without any subarrays.
>
> Does that not depend how literally one takes the "an object is an
> array of length one" rule?
>
> (I'm not being 100% serious here. It's obviously intended to
> mean, "an object is the sole element in an array of length one".)
I believe the rule about treating objects as an array of length
one does not enter into the question; all that matters is the
types involved. The type of &i is pointer to int. However, if
we did this
int i;
char *cp = ( (char (*)[sizeof i]) &i )[1];
then there would again be undefined behavior, because now the
type of the expression before the [1] is a pointer-to-array type,
and so that expression ultimately gets converted to a pointer to
an element of the second subarray.
> I've cut the rest of your very helpful explanation except for a
> detail:
>
>> If you don't mind using a cast or compound literal, you can use
>> the &x+1 form regardless of whether x is a scalar or an array:
>>
>> char result[20];
>> char *ep = (void*){ &result + 1 };
>
> We're are talking about C++ here. Maybe there is some default
> constructor equivalent of this.
Sorry, yes. In some cases in C, and in C++, using a cast may be
the only option:
char result[20];
char *ep = (char*)( &result + 1 );
Probably it's true that in C++ something could be done to avoid
having to use a cast, but unfortunately I find the rules for
automatic conversions ("coercions") in C++ too complicated to
offer a reliable answer to the question.