Click here to Skip to main content
15,886,919 members
Articles / Programming Languages / C++/CLI
Article

The Stupid XOR Trick

Rate me:
Please Sign up or sign in to vote.
3.58/5 (28 votes)
13 Aug 2002CPOL2 min read 248.2K   39   130
Explaining the phenomenon of x^=y^=x^=y;

Introduction

As a result of many, sometimes insulting, reactions on my signature, I decided to write an article on this topic. The mentioned signature looks like this:

int x=1, y=5; 
x^=y^=x^=y; // what's the content of x and y now?

Well, the reactions range from "that's not even valid C/C++ code" to "that works only with X=1 and y=5" and "you better learn C". To all these unbelievers and of course everyone else who doesn't know this "trick"; may this article enlighten you :)

What it's meant to do

Simply exchange the values of two integer variables without using a temporary variable. It gives unpredictable results with other variable types than integer types.

The symbol ^ is the XOR operator used in C/C++. See the article from PJ Arends on Bitwise Operators for a full introduction to bits and related operators.

The questionable code fragment x^=y^=x^=y; can be expanded into x XOR y XOR x XOR y. Since C/C++ resolves expressions like this from right to left, we can split it into the steps performed by the compiler:

x ^= y; // the right-most expression
y ^= x; // the middle expression
x ^= y; // the left-most expression

Which can be further expanded into

x = x ^ y; // x = 1 XOR 5  -> x = 4
y = y ^ x; // y = 5 XOR 4 = 1  -> y = 1
x = x ^ y; // x = 4 XOR 1 = 5  -> x = 5

Voila, here we are x=5 and y=1. That's what we wanted to achieve. And all this without using a temporary variable like in int t = x; x = y; y = t; which most programmers use. I confess that my method is confusing to most people because it's a little known method. As an additional benefit, the compiler can translate it into 3 simple XOR assembler statements.

Sample

For all who still don't believe it, here is a sample program to prove  that it works (with any integer number). The sample can be compiled in Ansi and Unicode and is compatible with VC6 and VC7. It is not using any library except the standard C Runtime Library.

#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>

int _tmain(int argc, TCHAR* argv[])
{
    if(argc != 3)
    {
        _tprintf(
            _T("\nUsage: StupidXORTricks.exe intvalue1 intvalue2\n"));
    }
    else
    {
        int x = _ttoi(argv[1]);
        int y = _ttoi(argv[2]);

        _tprintf(_T("x = %d, y = %d\n"), x, y);
        _tprintf(_T("Performing x^=y^=x^=y...\n"));
		
        x^=y^=x^=y;

        _tprintf(_T("x = %d, y = %d\n"), x, y);

    }
    return 0;
}

Finally, I hope that I don't get any more responses to my sig. :)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Portugal Portugal
Software Smith, Blacksmith, Repeat Founder, Austrian, Asgardian.

Comments and Discussions

 
GeneralMy vote of 1 Pin
.:floyd:.23-Feb-14 1:27
.:floyd:.23-Feb-14 1:27 
GeneralRe: My vote of 1 Pin
Andreas Saurwein23-Feb-14 4:08
Andreas Saurwein23-Feb-14 4:08 
GeneralRe: My vote of 1 Pin
.:floyd:.23-Feb-14 12:21
.:floyd:.23-Feb-14 12:21 
GeneralSee this. Pin
Nibu babu thomas7-Nov-05 17:27
Nibu babu thomas7-Nov-05 17:27 
GeneralRe: See this. Pin
toxcct26-Feb-06 23:42
toxcct26-Feb-06 23:42 
GeneralRe: See this. Pin
Nibu babu thomas26-Feb-06 23:43
Nibu babu thomas26-Feb-06 23:43 
GeneralRe: See this. Pin
toxcct26-Feb-06 23:45
toxcct26-Feb-06 23:45 
GeneralRe: See this. Pin
Nibu babu thomas26-Feb-06 23:48
Nibu babu thomas26-Feb-06 23:48 
GeneralRe: See this. Pin
toxcct26-Feb-06 23:51
toxcct26-Feb-06 23:51 
GeneralRe: See this. Pin
Nibu babu thomas26-Feb-06 23:52
Nibu babu thomas26-Feb-06 23:52 
GeneralRe: See this. Pin
toxcct26-Feb-06 23:54
toxcct26-Feb-06 23:54 
GeneralRe: See this. Pin
Nibu babu thomas26-Feb-06 23:56
Nibu babu thomas26-Feb-06 23:56 
GeneralTrick subject to compiler (eek, gcc 3.x) Pin
Anonymous17-Aug-05 14:18
Anonymous17-Aug-05 14:18 
GeneralA tiny &quot;proof&quot; for the trick, just for fun Pin
Humpzlopogas15-Nov-03 17:37
Humpzlopogas15-Nov-03 17:37 
GeneralRe: A tiny &quot;proof&quot; for the trick, just for fun Pin
Andreas Saurwein16-Nov-03 4:07
Andreas Saurwein16-Nov-03 4:07 
GeneralRe: A tiny "proof" for the trick, just for fun Pin
.:floyd:.23-Feb-14 1:14
.:floyd:.23-Feb-14 1:14 
This merely proves, that the arithmetic is correct. It neglects additional rules, imposed and specified by the programming language. In particular the rule, that the stored value of an object shall not be modified more than once between sequence points. There is a sequence point just before and after the expression x^=y^=x^=y. The stored value of x is assigned to twice. This constitutes undefined behavior.

Preemptive "But I tried it, and it works"-batter: Appearing to work is a valid form of undefined behavior. It is still undefined.

Reference: C99 6.5#2:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.73)

73) This paragraph renders undefined statement expressions such as
    i = ++i + 1;
    a[i++] = i;
while allowing
    i = i + 1;
    a[i] = i;

C11 6.5#2:
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.84)

84) This paragraph renders undefined statement expressions such as
    i = ++i + 1;
    a[i++] = i;
while allowing
    i = i + 1;
    a[i] = i;

GeneralOld trick Pin
Dimitris Vasiliadis26-Sep-03 22:56
Dimitris Vasiliadis26-Sep-03 22:56 
GeneralRe: Old trick Pin
Prakash Nadar1-Dec-03 16:43
Prakash Nadar1-Dec-03 16:43 
GeneralRe: Old trick Pin
Dimitris Vasiliadis1-Dec-03 18:56
Dimitris Vasiliadis1-Dec-03 18:56 
GeneralRe: Old trick Pin
Prakash Nadar1-Dec-03 21:16
Prakash Nadar1-Dec-03 21:16 
Generalx ^= y ^= x ^= y is undefined. Period. Pin
stickboy20-May-03 17:57
stickboy20-May-03 17:57 
GeneralRe: x ^= y ^= x ^= y is undefined. Period. Pin
Andreas Saurwein21-May-03 4:29
Andreas Saurwein21-May-03 4:29 
GeneralRe: x ^= y ^= x ^= y is undefined. Period. Pin
stickboy21-May-03 17:36
stickboy21-May-03 17:36 
GeneralRe: x ^= y ^= x ^= y is undefined. Period. Pin
Andreas Saurwein22-May-03 0:03
Andreas Saurwein22-May-03 0:03 
GeneralRe: x ^= y ^= x ^= y is undefined. Period. Pin
stickboy22-May-03 7:11
stickboy22-May-03 7:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.