Malcolm said:
Why isn't
void memswap(void *ptr1, void *ptr2, size_t len)
part of the standard library?
The function is easy to write, but if it was part of the standard then you
could write code like
memswap(&x, &y, sizeof(double));
knowing that any half-decent compiler would optimise it to a few inlined
instructions.
Well, since nobody else will answer your question, I'll give it a
shot. For small sized types like this, this is how I deal with the
issue:
#define swapType (type, x, y) { \
type tmp_NAMESPACE_OBFUSCATION_XJgb75b6978t; \
tmp_NAMESPACE_OBFUSCATION_XJgb75b6978t = x; \
x = y; \
y = t; \
}
This allows the compiler to use type specific mechanisms to perform
the swap. This matters on processors like the Athlon which physically
seperates that FPU and INT portions of the CPU (if you use an opaque
mechanism for trying to move the data, you may incurr large
performance penalties because of this.)
I think the compiler can use FP registers in something like:
memswap(&x, &y, sizeof(double));
as you suggest, but the compilers ability to do this might be very
narrow. For example if you did this:
memswap(&t.x, &t.y, sizeof(double));
The vendor might conclude that it shouldn't do this if t is a union.
Using FP registers might *normalize* the value while swapping it,
which would make the integer images change in unexpected ways. While
the ANSI committee could write all sorts of irrelevant verbiage about
how something is undefined, or not, their rubber stamp will not
override the desire of vendors who wanted to both simplify the
implementation (and not perform the optimization you are hoping for)
and make sure it was bit preserving to follow the principle of least
surprise.
Using the macro I showed above, you could instead use the following
alternative:
swapType (double, x, y);
Which takes fewer keystrokes, is more flexible, doesn't take a
function call hit, etc, etc.
I discuss various ways of swapping on my website:
http://www.azillionmonkeys.com/qed/case3.html