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
This does not necessarily work fine for
int
according to the standand. Imagine the case wherex
andy
wereINT_MAX
andINT_MAX-1
respectively. The first addition statement would result in a signed overflow which is undefined by the standard.A more reliable implementation of the swap macro for
int
would be the XOR swap algorithmSimply put: you cannot make a generic swap macro in C, at least, not without some risk or headache. (See other posts. Explanation lies below.)
Macros are nice, but the problem you'll run into with actual code would be data type issues (as you've stated). Furthermore, macros are "dumb" in a way. For example:
With your example macro
#define swap(x,y) { x = x + y; y = x - y; x = x - y; }
,swap(++x, y)
turns into{ ++x = ++x + y; y = ++x - y; ++x = ++x - y;}
.If you ran
int x = 0, y = 0; swap(++x, y);
you'd getx=2, y=3
instead ofx=0, y=0
. On top of this, if any of the temp variables in your macro appear in your code, you could run into some annoying errors.The functionality you're looking for were introduced in C++ as templates. The closest you can get in C is using an inline function for each data type imaginable or a decently complex macro (see previous macro issues and previous posts).
Here's what that the solution using templates in C++ looks like:
In C you'd need something like:
or (as mentioned a few times) a fairly complex macro which has potential to be hazardous.
Seriously, how many swaps do you have to do in your code that it is worth all the headaches coming up here in this thread with the given solutions? I mean, this is not a 10 line complicated and error prone code structure, it is a well-known idiom with one temporary variable and three simple assignments. Write it where you need it, even in one line if you want to save space:
Or use a "local" macro where a and b are more complex.
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:
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.
You can do something like this:
which you would then invoke like this:
or:
If you are happy to use gcc-specific extensions then you can improve on this like so:
and then it would just be:
or:
This works for most types, including pointers.
Here is a test program:
GMan started this attempt, to code this in combination of an
inline
function and a macro. This solution supposes that you have modern C compiler that supports C99, since it uses a compound literal:This has the following properties:
a
andb
only once.The cast
(ptrdiff_t)
is needed such that the-1
is not silently promoted toSIZE_MAX
.This solution still suffers from two drawbacks:
It is not type safe. It only checks for the sizes of the types, not their semantics. If the types differ, say a
double
of size 8 and auint64_t
, you are in trouble.The expressions must allow the
&
operator to be applicable. Thus it will not work on variables that are declared with theregister
storage class.