If you are only using integer types ( int
, long
, unsigned char
, ...) you can use a trick with XOR, like this:
x ^= y;
y ^= x;
x ^= y;
There is no limitation to the magnitude of the value. Yes, it works with INT_MAX
. Try to pick a pair of numbers and make that calculation on hand to understand how it works.
If you want to implement a macro that works for any type, we have some possibilities. The simplest form is as follows:
#define SWAP(x, y) do { \
typeof(x) temp = x; \
x = y; \
t = temp; \
} while (0)
This works for the general case, but has some problems. First, it depends on an extension of GCC, typeof
. This is not present in all compilers. Second you can pass different types to x and y, and this should not be allowed. And finally, if one of the variables is called temp
, you will have the macro crashing silently.
Note that if you use the macro option, technically you will never actually see the additional variable. So it is as if it did not exist, an abstraction.
To make a more bold version, I took one based on @adamk :
#define SWAP(x, y) do { \
unsigned char temp##x##y[sizeof(x) == sizeof(y) ? sizeof(x) : -1]; \
memcpy(temp##x##y, &y, sizeof(x)); \
memcpy(&y, &x, sizeof(x)); \
memcpy(&x, temp##x##y, sizeof(x)); \
} while(0)
Unfortunately the highlight is wrong there. Ignore this.
The first step is to declare a variable whose name is temp##x##y
. This counts on temp
, x
and y
, ensuring that the identifier is never equal to either. Then an array is declared with sizeof(x)
bytes. But note that if sizeof(x) != sizeof(y)
, the size will be -1
and the compilation will fail. Finally the copy is done using memcpy
. It may seem inefficient but in reality it is not. If the size is small the compiler will remove this and make the copy directly. If the size is large (for a huge struct), memcpy
is the quickest way to do this anyway. Note that typeof
is not used.