From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 2129B3861010 for ; Thu, 26 Nov 2020 17:06:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 2129B3861010 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A6F5931B; Thu, 26 Nov 2020 09:06:54 -0800 (PST) Received: from localhost (e121540-lin.manchester.arm.com [10.32.98.126]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 335403F23F; Thu, 26 Nov 2020 09:06:54 -0800 (PST) From: Richard Sandiford To: Martin Sebor Mail-Followup-To: Martin Sebor , gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Cc: gcc-patches@gcc.gnu.org Subject: Re: [07/23] Add a class that multiplexes two pointer types References: Date: Thu, 26 Nov 2020 17:06:52 +0000 In-Reply-To: (Martin Sebor's message of "Wed, 25 Nov 2020 16:33:26 -0700") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-6.6 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Nov 2020 17:06:56 -0000 Martin Sebor writes: > I do have one concern: the tendency to prioritize efficiency > over safety (this can be said about most GCC code). Specifically > in this class, the address bit twiddling makes me uneasy. I don't > think the object model in either language (certainly not C but > I don't have the impression C++ either) makes it unequivocally > valid. On the contrary, I'd say many of us interpret the current > rules as leaving it undefined. There are efforts to sanction > this sort of thing under some conditions (e.g, the C object > model proposal) but they have not been adopted yet. I think > we should try to avoid exploiting these dark corners in new > code. I'd tried to stick to operations that I thought were well-defined. The primitives being used are really: (1) convert a T1* or T2* to char* (2) increment an unincremented char* (3) decrement an incremented char* (4) convert a char* back to T1* or T2* (5) convert a char* to an intptr_t in order to test its low bit I thought (1) and (4) were allowed. At least, [basic.compound] says that void* must be able to hold any object pointer and that it must have the same representation as char*, so I thought the conversion in (1) was guaranteed to be representable. And (4) only ever undoes (1): it only converts the result of (1) back to the original pointer type. For (2) and (3), the incremented pointer will still be within the containing object, so I thought it would be well-defined. Here too, (3) only ever undoes (2): it only decrements a pointer that had previously been incremented. One thing I'd deliberately tried to avoid was converting integers =E2=80=9Cback=E2=80=9D to pointers, because that seemed like a more dangero= us thing. That's why: >> +template >> +inline T2 * >> +pointer_mux::second_or_null () const >> +{ >> + // Micro optimization that's effective as of GCC 11: compute the value >> + // of the second pointer as an integer and test that, so that the int= eger >> + // result can be reused as the pointer and so that all computation can >> + // happen before a branch on null. This reduces the number of branch= es >> + // needed for loops. >> + return uintptr_t (m_ptr - 1) & 1 ? nullptr : known_second (); >> +} is written in a somewhat indirect way. Are your concerns with the primitives above, or is the problem with something else? Thanks, Richard