On 08/12/11 16:32, Paul LaFollette wrote:
Kind people,
I am befuddled, and looking for understanding:
int a, b;
a = 7;
b = 12;
a ^= b;
b ^= a;
a ^= b;
should swap the contents of a and b (and it does).
Since ^= associates to the right
a ^= b ^= a ^= b;
should do the same thing (and it does).
However, if I access a and b through pointers, it breaks.
int *p;
int *q;
p =&a;
q =&b;
*p ^= *q ^= *p ^= *q;
puts the original contents of *p into *q, but puts 0 into *p.
Specifically, the following program, compiled with gcc 4.1.2 yields the
results listed below it:
#include<stdlib.h>
#include<stdio.h>
int main()
{
int a, b;
int *p, *q;
p =&a;
q =&b;
a = 55;
b = 27;
printf("before a = %d b = %d\n", a, b);
a ^= b ^= a ^= b;
printf("after a = %d b = %d\n", a, b);
printf("before *p = %d *q = %d\n", *p, *q);
*p ^= *q ^= *p ^= *q;
printf("after *p = %d *q = %d\n", *p, *q);
return 0;
}
before a = 55 b = 27
after a = 27 b = 55
before *p = 27 *q = 55
after *p = 0 *q = 27
So, is this an "I don't understand C as well as I thought I did" issue, or
might it be a compiler issue?
I'd also recommend you buy a bigger screen, so that you don't have to
squeeze your code so much that you write such unintelligible code.
There are only two places where something like "a ^= b ^= a ^= b;" is
acceptable - compiler torture tests, and the obfuscated C competitions.
For every other use, the correct code is:
int temp = a;
b = a;
a = temp;
It's much clearer, it always works, in many cases it will run faster
(since it avoids data pipeline stalls, and gives the compiler a better
chance at optimisations).