- #1
- 37,626
- 9,862
@sysprog posted this code for a nifty swap function that uses XOR in another thread in this section.
Here's the references version:
This function is called like this:
After swapRefs() returns, a's value will be 8 and b's value will be 5.
Here's the pointers version:
This function is called like so:
After swapPtrs() returns, a's value will be 8 and b's value will be 5, which is what you would expect.
So far, this shouldn't be too surprising, and may even be a bit ho-hum.
What's very interesting to me in a very nerdy way is that, even though the calling semantics of the two swap functions and what happens in the function bodies are quite different, the underlying assembly code (in the MSFT Visual Studio implementation) is identical.
swapRefs() assembly code - the lines of C++ code are shown in comments.
swapRefs() assembly code
This put me in mind of a couple of swap routines that I did awhile back: one with references and one with pointers. Unlike the example above, both routines do use a third memory location. Rather than wander off-topic, I thought I'd just start a new thread.sysprog said:C:void XorSwap( int* x, int* y ) { /* ensure that you're not swapping a location with itself (3 XORs would zero it out as surely as 1 XOR would) */ if (x != y) { *x ^= *y; /* xor x with y and store the result at x */ *y ^= *x; /* xor y with x and store the result at y */ *x ^= *y; /* xor x with y and store the result at x */ /* x and y have been swapped without a 3rd memory location */ } }
Here's the references version:
C++:
// Swap two numbers, using reference parameters
// x and y are references to the a and b variables in main()
void swapRefs(int& x, int& y)
{
int temp;
temp = x;
x = y;
y = temp;
}
C++:
int a = 5;
int b = 8;
swapRefs(a, b);
Here's the pointers version:
C++:
// Swap two numbers, using pointer parameters
// x and y are pointers to the a and b variables in main()
void swapPtrs(int* x, int* y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
C++:
int a = 5;
int b = 8;
swapPtrs(&a, &b);
So far, this shouldn't be too surprising, and may even be a bit ho-hum.
What's very interesting to me in a very nerdy way is that, even though the calling semantics of the two swap functions and what happens in the function bodies are quite different, the underlying assembly code (in the MSFT Visual Studio implementation) is identical.
swapRefs() assembly code - the lines of C++ code are shown in comments.
Code:
// int temp;
// temp = x;
mov eax,dword ptr [x]
mov ecx,dword ptr [eax]
mov dword ptr [temp],ecx
// x = y;
mov eax,dword ptr [x]
mov ecx,dword ptr [y]
mov edx,dword ptr [ecx]
mov dword ptr [eax],edx
// y = temp;
mov eax,dword ptr [y]
mov ecx,dword ptr [temp]
mov dword ptr [eax],ecx
swapRefs() assembly code
Code:
// int temp;
// temp = *x;
mov eax,dword ptr [x]
mov ecx,dword ptr [eax]
mov dword ptr [temp],ecx
// *x = *y;
mov eax,dword ptr [x]
mov ecx,dword ptr [y]
mov edx,dword ptr [ecx]
mov dword ptr [eax],edx
// *y = temp;
mov eax,dword ptr [y]
mov ecx,dword ptr [temp]
mov dword ptr [eax],ecx