It's often more of a danger (in your case it's actually undefined behavior; plus if one number is zero, things go wrong). Unless you're cripplingly low on memory, it's better to just use a temp variable (or the stl swap function). This is more clear about what you're doing and easier to maintain.
the way you have written it, it is undefined behavior. This is because you are modifying a variable more than once in the same sequence point. However if you rewrite it as follows:
m ^= n;
n ^= m;
m ^= n;
then it is safe. However, "useful" is another question, it is rarely "useful" and sometimes it is actually slower than actually using a temp!
Also you need to be careful with aliasing (pointers/references) because if you try to swap something with itself, then you end up accidentally zeroing your value. For example:
#define SWAP(m, n) { m ^= n; n ^= m; m ^= n; }
int x[] = { 1, 2, 3, 4 };
int i = 0;
int j = 0;
SWAP(x[i], x[j]); // whoops, x[0] == 0 now, not 1!
a more traditional swap implementation doesn't have this issue.
No, it is undefined behaviour in both C and C++. It may work sometimes, but you should not rely on it.
Also even the "fixed" variation doesn't always work:
m ^= n;
n ^= m;
m ^= n;
This fails if m and n are references to the same variable. In this case it sets the value to zero.
C doesn't have references but even in C there are still dangers lurking if you try to use this trick:
- You may try to put the "working" version into a macro SWAP, but that can fail if called with SWAP(x, x), setting x always to zero.
You may try to extend the trick to swapping two values in an array, but again this can fail if you use the same index:
a[m] ^= a[n]; a[n] ^= a[m]; a[m] ^= a[n];
Now if m == n again the value of a[m] is set to zero.
Please don't use "clever" tricks like this. Use a temporary variable to swap two values.
with that trick, you save an extra memory location to save a temporary value. It may be efficiant for integers, but is that readable ? Your last generation optimizer may do the same.