Click here to Skip to main content
15,888,282 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.4K   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

 
GeneralRe: Is this method actually faster? Pin
Chris Losinger14-Aug-02 7:24
professionalChris Losinger14-Aug-02 7:24 
GeneralRe: Is this method actually faster? Pin
Chris Losinger14-Aug-02 14:29
professionalChris Losinger14-Aug-02 14:29 
GeneralRe: Is this method actually faster? Pin
Andreas Saurwein14-Aug-02 14:42
Andreas Saurwein14-Aug-02 14:42 
GeneralRe: Is this method actually faster? Pin
Raskolnikov14-Aug-02 16:46
Raskolnikov14-Aug-02 16:46 
GeneralSorry Pin
Raskolnikov15-Aug-02 10:30
Raskolnikov15-Aug-02 10:30 
GeneralRe: Is this method actually faster? Pin
Henry Jacobs15-Aug-02 7:53
Henry Jacobs15-Aug-02 7:53 
GeneralRe: Is this method actually faster? Pin
Henry Jacobs15-Aug-02 7:56
Henry Jacobs15-Aug-02 7:56 
GeneralRe: Is this method actually undefined? Pin
UltraJoe21-Aug-02 5:37
UltraJoe21-Aug-02 5:37 
Russ Freeman wrote:
And there is one more interesting little thing about this code...

It is dangerous as the outcome is undefined according to the spec. See the C FAQ for details at http://www.eskimo.com/~scs/C-faq/q3.1.html[^]

For another example of undefined behaviour see this: http://www.eskimo.com/~scs/C-faq/q3.3.html[^]

So, whilst the code works today you may be scratching your head wondering why the latest patch or upgrade has broken your application only to discover that the undefined behaviour you took advantage is now undefined in a completely different way Good Luck.

In the same vane...which function is executed first?
int a = b() + c() * d();


Actually, I'm not convinced this would be considered a side-effect. Consider the more common:

int a;
int b;
int c;

a = b = c = 5;


Now, given that there's no guarantee what the values of a, b, and c are before initialization, what is the result of this operation? Obviously, a doesn't take on whatever value b had before initialization, nor b c's. It evaluates right-to-left.

Likewise, since the author is using assignment operators (even the "modifying" ones), my interpretation is that the results would not be undefined/unspecified/implementation-defined, or, if they are, that the standard chain-initialization would also be undefined/unspecified/implementation-defined. This wouldn't be a "side-effect" any more than "a = a + 1" would be.
GeneralRe: Is this method actually undefined? Pin
UltraJoe21-Aug-02 6:03
UltraJoe21-Aug-02 6:03 
AnswerRe: Is this method actually faster? Pin
Goran Mitrovic14-Aug-02 12:48
Goran Mitrovic14-Aug-02 12:48 
GeneralRe: Is this method actually faster? Pin
Tim Smith14-Aug-02 13:42
Tim Smith14-Aug-02 13:42 
GeneralRe: Is this method actually faster? Pin
Goran Mitrovic14-Aug-02 15:12
Goran Mitrovic14-Aug-02 15:12 
GeneralRe: Is this method actually faster? Pin
Raskolnikov14-Aug-02 15:54
Raskolnikov14-Aug-02 15:54 
AnswerRe: Is this method actually faster? Pin
Gimpy13-Mar-03 15:00
Gimpy13-Mar-03 15:00 
GeneralIts not stupid and its not a trick Pin
Roger Allen14-Aug-02 6:35
Roger Allen14-Aug-02 6:35 
GeneralRe: Its not stupid and its not a trick Pin
Andreas Saurwein14-Aug-02 12:58
Andreas Saurwein14-Aug-02 12:58 
Generalsimply great! Pin
SteveKing14-Aug-02 4:14
SteveKing14-Aug-02 4:14 
GeneralRe: simply great! Pin
Andreas Saurwein14-Aug-02 4:16
Andreas Saurwein14-Aug-02 4:16 
GeneralRe: simply great! Pin
Jörgen Sigvardsson14-Aug-02 4:45
Jörgen Sigvardsson14-Aug-02 4:45 
GeneralRe: simply great! Pin
Andreas Saurwein14-Aug-02 5:51
Andreas Saurwein14-Aug-02 5:51 

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.