Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ames!killer!chasm From: chasm@killer.Dallas.TX.US (Charles Marslett) Newsgroups: comp.unix.questions Subject: Re: Re^2: Bit Switching - How? Summary: not XOR pointers, XOR data! Message-ID: <7815@killer.Dallas.TX.US> Date: 11 Apr 89 11:37:43 GMT References: <1138@uvm-gen.UUCP> <9977@smoke.BRL.MIL> <2345@van-bc.UUCP> <1558@zen.UUCP> Organization: The Unix(R) Connection, Dallas, Texas Lines: 60 In article <1558@zen.UUCP>, frank@zen.co.uk (Frank Wales) writes: :: In article <1574@lznv.ATT.COM> jlw@lznv.ATT.COM (J.L.WOOD) writes: :: >> sl@van-bc.UUCP (pri=-10 Stuart Lynne) writes: :: >> \For fast generic swapping I use: :: >> :: >> \#define swap(a,b) {a^=b;b^=a;a^= b;} :: >> :: > :: >Also be careful how you use this algorithm if you are using pointers. :: >I once used this method in a sorting routine as my basic exchange and :: >got badly burned. :: > :: >If a and b point to the same location, you get zero as in 0, nada, goose egg. :: :: Well, this surprised me, since blurfl^blurfl does give 0, but blurfl^0 :: gives blurfl again, so you should get it back, unless some pretty funky :: pointer-to-int conversion is taking place. I tried the following :: myself (admittedly on a fairly well-behaved machine from HP), The problem is that the second part "blurfl^0" is really "0^0" and if the original algorithm works at all, the result of swapping "blurfl" with "blurfl" will be zero. :: #include :: #define ptr_swap(a,b) (a=(void *)((unsigned long)a^(unsigned long)b),\ :: b=(void *)((unsigned long)a^(unsigned long)b),\ :: a=(void *)((unsigned long)a^(unsigned long)b)) :: :: main(argc,argv) :: char *argv[]; :: { :: char *a=argv[0],*b=argv[0]; :: :: (void)printf("a=%lx, b=%lx\n",(unsigned long)a,(unsigned long)b); :: ptr_swap(a,b); The mistake you made here is that you are swapping "a" and "b", too uncover the problem with the macro, try substituting the following line: ptr_swap(a,a); The problem arises with pointers because that is where aliasing (and calling a subroutine with two arguments that are the same address) becomes a problem, not because the swapped values are pointers. What I mean to say, is that the problem is an aliasing one, not a pointer one (Fie!, I can't say anything clearly today...). :: (void)printf("a=%lx, b=%lx\n",(unsigned long)a,(unsigned long)b); :: return 0; :: } :: -- :: Frank Wales, Systems Manager, [frank@zen.co.uk<->mcvax!zen.co.uk!frank] :: Zengrange Ltd., Greenfield Rd., Leeds, ENGLAND, LS9 8DB. (+44) 532 489048 x217 Charles =========================================================================== Charles Marslett STB Systems, Inc. <== Apply all standard disclaimers Wordmark Systems <== No disclaimers required -- that's just me chasm@killer.dallas.tx.us