0

I learned using Xor operator to swap two integers,like:
int a = 21;
int b = 7;
a^=b^=a^=b;

I would finally get a=7 and b=21.

I try to use xor operator on array like this way:

int main() { int a[] = {7,21}; a[0]^=a[1]^=a[0]^=a[1]; cout << a[0] <<',' <<a[1]; return 0; } 

The output is 0,7
I compile the code on Xcode and g++, they have the same issue.

Xor swap on array works fine with multiple lines:

int main() { int a[] = {7,21}; a[0]^=a[1]; a[1]^=a[0]; a[0]^=a[1]; cout << a[0] <<',' <<a[1]; return 0; } 

I would get output as 21,7

Here is the information what I already find:
- the issue is about sequence point: Array + XOR swap fails
- even for simple integers, they may have side affect to this undefined behavior: Why is this statement not working in java x ^= y ^= x ^= y;
- some other issue on xor swap: Weird XOR swap behavior while zeroing out data

So I should avoid using xor swap, instead, swap with temp would guarantee correct result.

But I still not very clear about what happen on a[0]^=a[1]^=a[0]^=a[1]; what is the sequence point issue with it?

I could not figure out what's the different on compiler between a[0]^=a[1]^=a[0]^=a[1]; and a^=b^=a^=b; ?


My doubt is:
" How does compiler output 0,7 for a[0]^=a[1]^=a[0]^=a[1];. "

I know this is sequence pointer issue, I could understand why printf("%d,%d",i++, i++); is undefined as some compiler parse parameter of function from left to right, and some do it from right to left.

But I do not know what is the problem on a[0]^=a[1]^=a[0]^=a[1];, it looks just the same as a^=b^=a^=b;. So I'd like to know how it works with array. So that I would know more about kind like "sequence pointer on index of array"

3

1 Answer 1

8

You cannot modify a variable more than once without an intervening sequence point, if you do so, it is Undefined Behavior.

a^=b^=a^=b; 

Trying to modify the values of a and b in the above statement breaks this rule and you end up with an Undefined Behavior.
Note that Undefined Behavior means that any behavior is possible and you can get any output.

Good Reads:

Sign up to request clarification or add additional context in comments.

6 Comments

Meaning, you should be all right if you add parentheses as appropriate, or stick to separate statements separated by ;
@DRVic: Parentheses won't help.
Really? a ^= ( b ^= ( a ^= b ) ) requires that a ^= b is first evaluated before the result is used in b ^= (a^=b) which must be evaluated before the result is used in a ^= ( b ^= ( a ^= b ) ).
@DRVic: Nope, not in C and C++. Only at a sequence point you can be sure which side effects have taken place and which haven't. See stackoverflow.com/q/4176328/395760
Note that this is no longer UB as of C++11.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.