To briefly answer your question, it is as the other answers have already stated. The #ifdef
/#ifndef
conditional only cares about the macro identifier, so the arguments are not part of its syntax.
However, your macro has a couple of weaknesses that should be addressed. First, note that using the XOR-operator for swapping, although a commonly taught trick to avoid using a temporary, fails if the two arguments are the same object. This is because the result of the first XOR would be 0, and the remaining XOR steps cannot recover the original value. Second, this version of the macro fails for pointer types, because XOR wants integral types. Third, the macro invokes the arguments multiple times, which will cause problems if the argument is an expression with side effects. Fourth, compound statements in a macro should be guarded by do
.. while (0)
to allow the macro to expand into a statement. This makes the macro syntactically cleaner, so that a semi-colon after it is not spurious.
As explained in a separate answer, in C++, use std::swap
instead of defining your own. Unfortunately, C does not provide a generic swapping utility function. However, it is not difficult to author a generic function:
static inline void swap_generic (void *a, void *b, void *t, size_t sz) {
if (a != b) {
memcpy(t, a, sz);
memcpy(a, b, sz);
memcpy(b, t, sz);
}
}
Your macro could then invoke this function.
#ifndef SWAP
# ifdef __cplusplus
# define SWAP(a, b) std::swap(a, b)
# else
# define SWAP_ASSERT(X) _Static_assert(X, #X)
# if __STDC_VERSION__ < 201112L
# undef SWAP_ASSERT
# define SWAP_ASSERT(X) struct dummy
# endif
# define SWAP(a, b) do { \
SWAP_ASSERT(sizeof(a) == sizeof(b)); \
char t[sizeof(a) != sizeof(b) ? -1 : sizeof(a)]; \
swap_generic(&(a), &(b), t, sizeof(a)); \
} while (0)
# endif
#endif
Note how we use std::swap
if C++ is detected.
If you use a C compiler that supports the typeof
extension, then the macro can be simplified greatly, since you do not need a generic swapping function.
#ifndef SWAP
# ifdef __cplusplus
# define SWAP(a, b) std::swap(a, b)
# else
# define SWAP(a, b) do { \
typeof(a) *p = &(a), *q = &(b), t = *p; \
*p = *q; \
*q = t; \
} while (0)
# endif
#endif
Note that the typeof
version promotes better type safety.