From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8108 invoked by alias); 30 Apr 2008 08:56:09 -0000 Received: (qmail 8096 invoked by uid 22791); 30 Apr 2008 08:56:07 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 30 Apr 2008 08:55:50 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m3U8tjUO006381; Wed, 30 Apr 2008 04:55:47 -0400 Received: from zebedee.pink (vpn-14-20.rdu.redhat.com [10.11.14.20]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m3U8tiDS031103; Wed, 30 Apr 2008 04:55:44 -0400 Message-ID: <4818340F.1080100@redhat.com> Date: Wed, 30 Apr 2008 10:13:00 -0000 From: Andrew Haley User-Agent: Thunderbird 2.0.0.12 (X11/20080213) MIME-Version: 1.0 To: Evan Jones CC: Rupert Wood , gcc-help@gcc.gnu.org Subject: Re: strict aliasing: how to swap pointers References: <481785A7.3060506@mit.edu> <00b701c8aa51$ef2c9b50$cd85d1f0$@net> <4817B98A.7090705@mit.edu> In-Reply-To: <4817B98A.7090705@mit.edu> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org X-SW-Source: 2008-04/txt/msg00402.txt.bz2 Evan Jones wrote: > Rupert Wood wrote: >> I don't know how to fight aliasing rules but as another approach you >> could template the function instead, i.e. >> >> template T* exchange(T** ptr, T* next); >> >> exchange(&a, &v2); >> >> since you're using C++ here. > > I initially dismissed this solution since the implementation of exchange > is either a typical swap using a temporary, a compare-and-swap sequence > or a mutex, depending on various compilation options. I wanted to avoid > including the implementation in the header to avoid a bunch of #ifdefs. > However, your email made me try to avoid the warning with a template > wrapper: > > > template > T* exchange_template(T** ptr, T* next) { > return reinterpret_cast( > exchange(reinterpret_cast(ptr), next)); > } > > ... > > exchange_template(&a, &v2); > > > I don't understand why, but this compiles without warnings. It also > avoids needing to look up the aliasing rules, and places the dangerous > cast in a single location, so this seems like a better solution. > > I would still like to know if my original solution is "correct" or not, > since it would be needed for C. We have no way to know, since you didn't provide us with the source of exchange(), and that's where the aliasing violation, if any, would occur. However, the answer is almost certainly no. I don't know why you're trying to do something so simple in such a difficult way. If you really want to do this in standard portable C, the easiest way is a macro: #define SWAP(TYPE, A, B) do { TYPE tmp = a; b = b; b = tmp; } while (0) You can't portably cast a pointer to an int* to a pointer to a void* and then dereference the resulting pointers since the things they point to might not even be the same size. The union hack will work on gcc, though. Andrew.