Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c++ Subject: Re: Is this really necessary Date: Sun, 06 Jun 2021 16:20:23 -0700 Organization: None to speak of Lines: 68 Message-ID: <87mts2vavc.fsf@nosuchdomain.example.com> References: <20210606103347.06e3663e23b85fa28ff9cd39@cvine--nospam--.freeserve.co.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: reader02.eternal-september.org; posting-host="da0ef0006e1a2be3c584df7adb5e6866"; logging-data="24247"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18covm9PzuSFd8VKkvq07UK" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) Cancel-Lock: sha1:m/AseWaBsZoyUu2DVW6RuE0l7UE= sha1:JT09PL+m1o07uHM/LJRlN3TYuzY= Xref: csiph.com comp.lang.c++:80203 Richard Damon writes: > On 6/6/21 5:33 AM, Chris Vine wrote: >> On Sat, 5 Jun 2021 19:08:49 -0400 >> James Kuyper wrote: >>> Apologies to David, who has already received two versions of this >>> message as e-mail, because I keep hitting the Thunderbird "Reply" button >>> instead of their new "Followup" button. >>> >>> On 6/5/21 9:29 AM, David Brown wrote: >>>> On 05/06/2021 15:06, Bonita Montero wrote: >>>>>> No.  Subtraction of pointers is defined as the difference in their >>>>>> indexes within a single array. >>>>> >>>>> That coudn't be true because you can cast any pointer-pair >>>>> to char *, subtract them and use the difference for memcpy(). >>>>> >>>> >>>> Look it up. >>> >>> That works in C because every C object can be accessed as an array of >>> char. C++ allows more complicated possibilities, including objects that >>> are not contiguous. But it works in C++ if the relevant objects are >>> required to be contiguous. If two such objects are both sub-objects of >>> the same larger object, the difference between those pointers satisfies >>> that requirement, otherwise the subtraction is undefined. >> >> Assuming C++20, on my (possibly faulty) reading you could _not_ access >> any given object as an array of char, but you could access it as an >> array of unsigned char or std::byte. This is because you can construct >> any object in an array of unsigned char or of std::byte, so that even >> where some other storage for a particular object has in fact been >> provided, such an array will implicitly arise in consequence of the >> carrying out of any pointer arithmetic which prods around in the >> object's internals. >> >> So although the strict aliasing rule is not offended by the use of >> char* for this purpose, I suspect the rules on pointer arithmetic are. > > I haven't poured over the standard recently, but my memory was that the > type family char / signed char / unsigned char all had this property, > but if you actually accessed the values, signed char (and char is > signed) had the possibility of a trap value (-0). I think you meant "(and char *if* signed)". As of C++17, signed types including signed char can use two's complement, ones' complement, or signed magnitude, but: For unsigned narrow character types, each possible bit pattern of the value representation represents a distinct number. These requirements do not hold for other types. which means that plain char and signed char have no trap representations and no padding bits. Drafts of C++20 permit only two's complement for signed integer types. (You're unlikely to find a pre-C++20 implementation that doesn't already meet that requirement.) I haven't looked into what the standard says about aliasing arbitrary objects with arrays of signed char. > unsigned char had the natural property that its values were precisely > defined by the standard, but any character type could be used, if only > because of ancient code that used char for this purpose. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */