This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: seemingly inconsistent behaviour of ^= with int *


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).


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]