Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!usc!ginosko!uunet!yale!mfci!karzes From: karzes@mfci.UUCP (Tom Karzes) Newsgroups: comp.lang.c Subject: Re: swap(x,y) Message-ID: <1009@m3.mfci.UUCP> Date: 7 Sep 89 01:30:14 GMT References: <784@skye.ed.ac.uk> <1267@levels.sait.edu.au> <149@cpsolv.UUCP> <1989Sep6.061301.17629@algor2.algorists.com> Sender: karzes@mfci.UUCP Reply-To: karzes@mfci.UUCP (Tom Karzes) Organization: Multiflow Computer Inc., Branford Ct. 06405 Lines: 53 In article <1989Sep6.061301.17629@algor2.algorists.com> jeffrey@algor2.UUCP (Jeffrey Kegler) writes: >One thing that makes > >A) #define swap(x,y) (x ^= y, x ^= y ^= x) > >seem more attractive than > >B) #define swap(x,y) {int tmp; tmp = x; y = tmp; x = y; } > >is the syntax. Not to mention the fact that B) doesn't work. Perhaps you meant: #define swap(x,y) {int tmp; tmp = x; x = y; y = tmp;} One advantage of this over A) is that swap(a,a) works. More realistically, swap(a[i],a[j]) works when i == j. Another advantage is that, though amusing, A) is absurd, likely to be inefficient, and likely to inhibit optimization. As far as style goes: When macros are written which should be thought of as statements, then they should have the syntax of statements. Yes, it's a bit ugly, but a good naming convention will make it obvious that the macro is in fact a macro. The problem is that function references, which in many contexts are thought of as statements, are really just expressions, and a semicolon is needed to turn the expression into a statement. If you want swap to be a statement with no defined result value, then you should not be required to supply a semicolon to make it a statement. Otherwise, if it is to be an expression with a defined value, then it should be like any other expression and require a semicolon to make it a statement. Unfortunately, in this case you can't use a block (i.e., a compound statement) because they aren't expressions in C and hence cannot have result values. >4) I think the idea of a global temporary to make Solution B an expression >is unworkable if your global temporary has its name used elsewhere >and ugly when it does work. Well, I'll agree that it's a bit ugly, but it certainly isn't unworkable. If you'll recheck the example, you'll see that the temporary is not global, but is local to the block defined by the macro. You therefore only have to ensure that it doesn't conflict with any name used in x or y. This is easily accomplished by prefixing the name with some prefix which is "owned" by the swap macro. For example, if you call the macro SWAP and designate any identifier beginning with SWAP_ as being private to the swap macro, then you could use the following with no risk of name conflict: #define SWAP(x,y) {int SWAP_tmp; SWAP_tmp = x; x = y; y = SWAP_tmp;} You could even make SWAP_tmp a global if you wanted, although this would probably force your compiler to keep it in memory.