awm@shamash.cdc.com (Allan Magnuson) (09/22/90)
There was a message a while back about not being able to create a good #define function to swap two variables. How about this one: #define swap(a,b) a^=b^=a^=b
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (09/22/90)
In article <26101@shamash.cdc.com> awm@shamash.UUCP (Allan Magnuson) writes: > There was a message a while back about not being able to create a good > #define function to swap two variables. > How about this one: #define swap(a,b) a^=b^=a^=b Is this in the FAQ list? That swap is slow, ugly, and won't work for pointers or floats on any machine. The best truly portable inline replacement for void swap(a,b) float *a; float *b; { float t = *a; *a = *b; *b = t; } is #define swap(a,b) do { float *swap_a = a; float *swap_b = b; float \ swap_t = *swap_a; *swap_a = *swap_b; *swap_b = swap_t; } while(0) which will fail only if any swap_* is defined as a macro. You can, of course, generalize this into swap(a,b,type). If you have a swap that is unsafe or uses its arguments by reference, please obey convention and give it an upper-only name like SWAP. ---Dan
horne-scott@cs.yale.edu (Scott Horne) (09/23/90)
In article <26101@shamash.cdc.com> awm@shamash.UUCP (Allan Magnuson) writes: >There was a message a while back about not being able to create a good >#define function to swap two variables. > >How about this one: #define swap(a,b) a^=b^=a^=b I prefer #define ___(_,__)(_^=__^=_^=__) It's delightfully difficult to read, isn't it? :-) "Oh, that? It swaps variables. Can't you tell?" :-) But it won't work on `float's and `double's, as `^' is defined only on integral types. --Scott -- Scott Horne ...!{harvard,cmcl2,decvax}!yale!horne horne@cs.Yale.edu SnailMail: Box 7196 Yale Station, New Haven, CT 06520 203 436-1817 Residence: Rm 1817 Silliman College, Yale Univ Uneasy lies the head that wears the _gao1 mao4zi_.
tac@cs.brown.edu (Theodore A. Camus) (09/24/90)
>There was a message a while back about not being able to create a good >#define function to swap two variables. > >How about this one: #define swap(a,b) a^=b^=a^=b >But it won't work on `float's and `double's, as `^' is defined only on >integral types. Nor would it work for swap(i,A[i]). In fact, the usual { tmp = i ; i = A[i] ; A[i] = tmp } would fail too. Thus the danger of call-by-name. [ref 2nd Dragon book] CSnet: tac@cs.brown.edu Ted Camus ARPAnet: tac%cs.brown.edu@relay.cs.net Box 1910 CS Dept BITnet: tac@browncs.BITNET Brown University "An ounce of example is worth a pound of theory." Providence, RI 02912
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (09/24/90)
In article <26101@shamash.cdc.com>, awm@shamash.cdc.com (Allan Magnuson) writes: > There was a message a while back about not being able to create a good > #define function to swap two variables. > > How about this one: #define swap(a,b) a^=b^=a^=b Hmm, let's see: double x, y; swap(x, y); Drat! Try again: char *x, *y; swap(x, y); Drat! Easy one: int i; swap(i, i); Drat! (i becomes 0) Using a GCC extension, we can do #define swap(x,y) do {typeof(x) ZZT = (x); (x) = (y); (y) = ZZT;} while (0) which works in a lot of cases, but has problems of its own. For example, swap(*p++, *--q); For the record, the version using assignments is often *faster* than the XOR-based version, as well as being more generally applicable. -- Heuer's Law: Any feature is a bug unless it can be turned off.