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.