andrew@otago.ac.nz (06/24/91)
I often get pissed off with the C pre-processor. Here is one thats been
getting up my wick for months.
#define SWAP(a, b) {int c; c = a; a = b; b = c}
if (spam)
SWAP(a, b);
else
a++;
These lines of code do a simple substitution
if (spam)
{
int c;
c = a;
a = b;
b = c
};
else
a++;
notice the }; on the last line of the substitution. This means that the else
is a syntax error! With swap, there are a number of simple solutions...
#define SWAP(a, b) (b = (b ^ a) ^ (a = (b ^ a) ^ a))
simple hu? but it only words with ints or longs.
Question time....
how do I define a swap macro that swaps two doubles, allows the ';' on the end
of the macro call, but does not cause a systax error when used in this context?
Andrew
andrew@otago.ac.nz
raichle@azu.informatik.uni-stuttgart.de (Bernd Raichle) (06/24/91)
From FAQ(comp.lang.c): Use #define SWAP(a, b) do{int c; c = a; a = b; b = c}while(0) -bernd
alanb@sdl.mdcbbs.com (06/24/91)
In article <1991Jun24.213932.595@otago.ac.nz>, andrew@otago.ac.nz writes: > I often get pissed off with the C pre-processor. Here is one thats been > getting up my wick for months. > > #define SWAP(a, b) {int c; c = a; a = b; b = c} > > if (spam) > SWAP(a, b); > else > a++; > > These lines of code do a simple substitution > > if (spam) > { > int c; > c = a; > a = b; > b = c > }; > else > a++; > > notice the }; on the last line of the substitution. This means that the else > is a syntax error! With swap, there are a number of simple solutions... > > #define SWAP(a, b) (b = (b ^ a) ^ (a = (b ^ a) ^ a)) > > simple hu? but it only words with ints or longs. > > Question time.... > how do I define a swap macro that swaps two doubles, allows the ';' on the end > of the macro call, but does not cause a systax error when used in this context? > > > Andrew > andrew@otago.ac.nz > Use overloaded inline functions in C++ inline void swap (double &a, double &b) {double c; c = a; a = b; b = c;} (unlikely to be an option, but (IMHO) the cleanest solution) or #define SWAP(a, b) do {double c; c = a; a = b; b = c} while (false) If you want the same macro to work with int or doubles #define SWAP(type, a, b) do {type c; c = a; a = b; b = c} while (false) (And call 'c' something else unless you are sure you will never have a macro argument that clashes with it e.g. use _m at the end of all variables declared inside macros - makes life easier with a debugger too. But I assume you just wanted nice short names for the illustration - reasonable.) Some compilers will give you a warning about "while (false)". This is a good sign - it proves they've worked out they don't need to put in any code to implement the loop :-) The other argument I've seen is if you use a macro, you should know about it and not use the semi-colon. Personally I only like this argument for things macros with unmatched braces, which couldn't be mistaken for (or replaced with) a function. alanb@sdl.mdcbbs.com Alan Braggins My opinions etc.
gwyn@smoke.brl.mil (Doug Gwyn) (06/24/91)
In article <1991Jun24.213932.595@otago.ac.nz> andrew@otago.ac.nz writes: >#define SWAP(a, b) {int c; c = a; a = b; b = c} >how do I define a swap macro that swaps two doubles, allows the ';' on the end >of the macro call, but does not cause a systax error when used in this context? This is not a C standards question. One obvious general solution is: #define MACRO(args) do { /*...*/ } while(0)
rob@meaddata.com (Robert E. Lancia) (06/25/91)
In article <1991Jun24.213932.595@otago.ac.nz> andrew@otago.ac.nz writes: >I often get pissed off with the C pre-processor. Here is one thats been >getting up my wick for months. > >#define SWAP(a, b) {int c; c = a; a = b; b = c} ^^ Notice that Andrew, as well as most of the replies I've seen so far, forgot the semi-colon after the b=c assignment. > [ . . . stuff deleted . . . ] >Andrew >andrew@otago.ac.nz Rob. -- |Robert Lancia | The above opinions | Mead Data Central |(513) 297-2560 | may not necessarily | Data Services Division |rob@pmserv.meaddata.com | be MDC's. Heck, they | P.O. Box 308 |...!uunet!meaddata!pmserv!rob | may not even be mine. | Dayton, Ohio 45401