The C FAQ declares that a generic SWAP macro in C is essentially impossible and not worth the effort. That sounds like a challenge to me.
It cites 2 main difficulties:
SWAP(my_int, my_float)
. A lot of compilers support decltype
style operators that make this easy, but they are nonstandard. For now I will admit defeat and just ask the user to supply a suitable type as the third argument.#
to stringify the input arguments and compare them to prospective temporary variable names to find one that doesn't match.#include <stdio.h>
#define SWAP(a,b,type) \
do { \
if ((#a[0] != 'a') && (#b[0] != 'a')){ \
type a_temp = a; \
a = b; \
b = a_temp; \
}else \
if ((#a[0] != 'b') && (#b[0] != 'b')){ \
type b_temp = a; \
a = b; \
b = b_temp; \
}else \
if ((#a[0] != 'c') && (#b[0] != 'c')){ \
type c_temp = a; \
a = b; \
b = c_temp; \
} \
} while(0)
int main()
{
int a_temp = 10, b_temp = 20, c_temp = 30;
printf("a_temp = %d, b_temp = %d, c_temp = %d\n", a_temp, b_temp, c_temp);
SWAP(a_temp, b_temp, int);
printf("a_temp = %d, b_temp = %d, c_temp = %d\n", a_temp, b_temp, c_temp);
SWAP(a_temp, c_temp, int);
printf("a_temp = %d, b_temp = %d, c_temp = %d\n", a_temp, b_temp, c_temp);
SWAP(b_temp, c_temp, int);
printf("a_temp = %d, b_temp = %d, c_temp = %d\n", a_temp, b_temp, c_temp);
return 0;
}
I've seen the issue of accidental capture brought up in many discussions and not seen anyone mention that you could do this, either to recommend or condemn it. Is this a good idea?
This will fail in some cases if the variables are lvalue expressions, eg, if you have int *a_temp
and int *b_temp
, and you SWAP(*a_temp, *b_temp, int)
. And since the macro is silently using "common" names like a_temp
, it might break if there is something like #define a_temp *a
.
And anyway, it is arguably not generic since you have to pass the type: SWAP(a, b, int)
is not fundamentally different from SWAPINT(a, b)
. If we accept passing the type, could we also accept passing the name of the temporary variable? Or even a fixed temporary variable name like _tmpswap0123456789
– after all, we are accepting the far more common name SWAP
to be now defined as this macro, so worrying about the name of a temporary variable inside it seems secondary.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.