Path: utzoo!utgpu!water!watmath!clyde!rutgers!sunybcs!bingvaxu!leah!itsgw!steinmetz!ge-dab!codas!killer!jfh From: jfh@killer.UUCP (John Haugh) Newsgroups: comp.lang.c Subject: Re: swap macro -- beware Summary: No, don't beware, just don't use. Message-ID: <3061@killer.UUCP> Date: 25 Jan 88 18:52:22 GMT References: <8801200422.AA19420@decwrl.dec.com> Organization: Big "D" Home for Wayward Hackers Lines: 50 In article <8801200422.AA19420@decwrl.dec.com>, devine@cookie.dec.com (Bob Devine) writes: > > #define swap(a,b) ((a) = ((b) = ((a) = (a) ^ (b)) ^ (b)) ^ (a)) > > He [the genius] says it will work for anything (int, char *, etc.). > > Well, yes and no. This old trick will work for those types that are > defined for the ^ op. That means structs, arrays, unions, bitfields, > and floats won't work the way you want. > -- > exit(Bob) -- the unique and naturally refreshing choice for an exit value This is a so old. I thought this was taught as the way _not_ to swap things. I learned the original in Pascal as an undergrad. Consider, what happens if A and B are both aliases for the same thing. Given that order of evaluation is not guaranteed, can you find and order of evaluation that this macro won't work for? To bring in a conversation from a different thread, consider: a ^= b; b ^= a; a ^= b; [ I think this was the code in that article ] What if, A and B are aliases? let's say, A = B = 7. after a ^= b, both a and b == 0. then, after both b ^= a and a ^= b (the second time), a and b are STILL == 0. If you assume the parenthesis are honored (and why not?), #define swap(a,b) ((a) = ((b) = ((a) = (a) ^ (b)) ^ (b)) ^ (a)) swap (X, X); becomes X = X ^ X; X = X ^ X; X = X ^ X; (which is the same as the above example) which also doesn't work. - John. -- John F. Haugh II SNAIL: HECI Exploration Co. Inc. UUCP: ...!ihnp4!killer!jfh 11910 Greenville Ave, Suite 600 "Don't Have an Oil Well? ... Dallas, TX. 75243 ... Then Buy One!" (214) 231-0993 Ext 260