Summary: Is this swap() macro correct?

brnstnd at stealth.acf.nyu.edu brnstnd at stealth.acf.nyu.edu
Sun Jan 21 14:30:09 AEST 1990


The macro is correct, except for namespace problems. I depend upon the
user not doing anything like swap(x,_MV_x,real)---after all, the user
isn't supposed to use such names. Then again, the macro shouldn't use
them either! Without better namespace management there's no solution.

do { ... } while(0) is the usual way to keep the macro working before an
else. (Any language that doesn't terminate all its control structures
should throw away its syntax and commit suicide, but that's a side issue.)
Sorry for not explaining this. By the way, an empty do { } while(0) fails;
define block as ``do { ;'' for general use.

Several people asked what was wrong with

  #define swap(x,y,typ) { typ tmp; tmp = y; y = x; x = tmp; }

There are two answers. The first is that this version has side effects.
A macro foo(a,b,c) should reference each of a, b, and c exactly once.
If the stdio macro writers understood this, putc(c,*f++) would work.

The second is a more general religious argument: Macros should feel like
functions. As above, they should reference each argument exactly once;
if an argument is modified, the macro should use a pointer to it instead;
and so on. The only exception is all-caps macros, which can do anything
they want. I wouldn't mind seeing this convention more widely observed.

---Dan



More information about the Comp.lang.c mailing list