#define swap(t, x, y) \
do { \
t safe ## x ## y; \
safe ## x ## y = x; \
x = y; \
y = safe ## x ## y; \
} while (0)
The code swaps arguments x and y of type t.
#define swap(t, x, y) \
do { \
t safe ## x ## y; \
safe ## x ## y = x; \
x = y; \
y = safe ## x ## y; \
} while (0)
The code swaps arguments x and y of type t.
The ## (double number sign) operator concatenates two tokens in a macro invocation (text and/or arguments) given in a macro definition. Read More
The double pound sign ##
is used for token concatenation.
This is how your code would look without pound key for simplicity.
#define swap(t, x, y) \
do { \
t safexy; \
safexy = x; \
x = y; \
y = safexy; \
} while (0)
You need to abide by the following rules when using ##
##
operator cannot be the very first or very last item in the
replacement list of a macro definition. ##
operator is
concatenated with first token of the item following the ##
operator. Concatenation takes place before any macros in arguments are expanded. If the result of a concatenation is a valid macro name, it is available for further replacement even if it appears in a context in which it would not normally be available.
If more than one ##
operator and/or #
operator appears in the
replacement list of a macro definition, the order of evaluation of
the operators is not defined.
For more understanding read here.
When you invoke this macro, for example like this:
swap(double, a, b);
it gets replaced by inline code to swap the two values, namely:
do {
double safeab;
safeab = a;
a = b;
b = safeab;
} while (0);
Things to note:
typeof(a)
, but that's not standard and thus not portable.)##
. This operator is available only in macro bodies and creates a new token by pasting the adjacent tokens together. Note that the name creation fails if one of the swapping operands are compound, e.g. a[i]
or p->x
. The name creation by concatenation is a bit overcareful. Because the swapping takes place in its own scope, it is safe to shadow variables, except those being swapped of course. Just pick a name outside your regular naming conventions and cross your fingers.do { ... } while (0)
wrapper is a common method to make the macro behave like a function, which is important if they are used as the only expression of an if
or while
body.Given that the macro doesn't work for compound expressions, you don't buy much with it. It also isn't type generic, because when you invoke the macro, the type must be known. Write a small static function for swapping; that's clearer in my opinion.
The C FAQ has a question and strong opinions about type-generic swap macros, too.