seemingly inconsistent behaviour of ^= with int *
David Brown
david.brown@hesbynett.no
Thu Dec 8 16:28:00 GMT 2011
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).
More information about the Gcc-help
mailing list