Implement generic swap macro in C [duplicate]

Possible Duplicate:
is there an equivalent of std::swap() in c

Hi folks,

I was attempting a problem to write a generic swap macro in C and my macro looks like this:

#define swap(x,y) { x = x + y; y = x - y; x = x - y; }

It works fine for integers and floats but I am unsure if there is any catch in it. What if by generic macro they mean swapping pointers, characters etc ? Can anyone help me with writing a generic macro for swapping every input ?

Thanks


Solution 1:

This works well only with integers.

For floats it will fail (e.g. try running it with a very large float and a very small one).

I would suggest something as follows:

#define swap(x,y) do \ 
   { unsigned char swap_temp[sizeof(x) == sizeof(y) ? (signed)sizeof(x) : -1]; \
     memcpy(swap_temp,&y,sizeof(x)); \
     memcpy(&y,&x,       sizeof(x)); \
     memcpy(&x,swap_temp,sizeof(x)); \
    } while(0)

memcpy is pretty optimized when the amount to copy is known at compilation time. Also, there's no need to manually pass a type name or use compiler specific extensions.

Solution 2:

You can do something like this:

#define SWAP(x, y, T) do { T SWAP = x; x = y; y = SWAP; } while (0)

which you would then invoke like this:

SWAP(a, b, int);

or:

SWAP(x, y, float);

If you are happy to use gcc-specific extensions then you can improve on this like so:

#define SWAP(x, y) do { typeof(x) SWAP = x; x = y; y = SWAP; } while (0)

and then it would just be:

SWAP(a, b);

or:

SWAP(x, y);

This works for most types, including pointers.

Here is a test program:

#include <stdio.h>

#define SWAP(x, y) do { typeof(x) SWAP = x; x = y; y = SWAP; } while (0)

int main(void)
{
    int a = 1, b = 2;
    float x = 1.0f, y = 2.0f;
    int *pa = &a;
    int *pb = &b;

    printf("BEFORE:\n");
    printf("a = %d, b = %d\n", a, b);
    printf("x = %f, y = %f\n", x, y);
    printf("pa = %p, pb = %p\n", pa, pb);

    SWAP(a, b);     // swap ints
    SWAP(x, y);     // swap floats
    SWAP(pa, pb);   // swap pointers

    printf("AFTER:\n");
    printf("a = %d, b = %d\n", a, b);
    printf("x = %f, y = %f\n", x, y);
    printf("pa = %p, pb = %p\n", pa, pb);

    return 0;
}