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