Swapping two integer numbers with no temporary variable I tried to swap 2 integer numbers without using an additional variable as a traditional swap.

Is it legal in C++? My VC compiler doesn't complain nor gives any warning about it. If so, how can I improve this script?

#include &lt;iostream&gt;

int main()
{
    int a = 20;
    int b = 66;

    // before swapping
    std::cout &lt;&lt; a  &lt;&lt; ' ' &lt;&lt; b  &lt;&lt; '\n';

    // swap
    a ^= b ^= a ^= b;

    // after swapping
    std::cout &lt;&lt; a &lt;&lt; ' ' &lt;&lt; b &lt;&lt; '\n';
}


For this code:

int a = 20;
int b = 66;
a ^= b ^= a ^= b;


Assembler output for VC++ 2013:


_b$ = -20                     ; size = 4
_a$ = -8                      ; size = 4

mov   DWORD PTR _a$[ebp], 20          ; 00000014H
mov   DWORD PTR _b$[ebp], 66          ; 00000042H

mov   eax, DWORD PTR _a$[ebp]
xor   eax, DWORD PTR _b$[ebp]
mov   DWORD PTR _a$[ebp], eax

mov   ecx, DWORD PTR _b$[ebp]
xor   ecx, DWORD PTR _a$[ebp]
mov   DWORD PTR _b$[ebp], ecx

mov   edx, DWORD PTR _a$[ebp]
xor   edx, DWORD PTR _b$[ebp]
mov   DWORD PTR _a$[ebp], edx



For this code:

int a = 20;
int b = 66;

int t = a;
a = b;
b = t;


Assembler output for VC++ 2013:


_t$ = -32                     ; size = 4
_b$ = -20                     ; size = 4
_a$ = -8                      ; size = 4

mov   DWORD PTR _a$[ebp], 20          ; 00000014H
mov   DWORD PTR _b$[ebp], 66          ; 00000042H

mov   eax, DWORD PTR _a$[ebp]
mov   DWORD PTR _t$[ebp], eax

mov   eax, DWORD PTR _b$[ebp]
mov   DWORD PTR _a$[ebp], eax

mov   eax, DWORD PTR _t$[ebp]
mov   DWORD PTR _b$[ebp], eax
You make assumptions which may not be true. Why do you believe that
int tmp = a;
a = b;
b = tmp;                                  

actually is compiled down to using an actual variable? It is likely just a register used on the CPU.
Have you inspected it?
Further, why do you assume that:
a ^= b ^= a ^= b;

uses fewer registers than a swap?
Really, what you should do is:
#include &lt;algorithm&gt;
#include &lt;iostream&gt;

int main() {

    int a = 20;
    int b = 66;

    // before swapping
    std::cout &lt;&lt; a  &lt;&lt; ' ' &lt;&lt; b  &lt;&lt; '\n';

    // swap
    std::swap(a,b);

    // after swapping
    std::cout &lt;&lt; a &lt;&lt; ' ' &lt;&lt; b &lt;&lt; '\n';

}

Which is also a reminder that having the a ^= b ^= a ^= b; 'naked' in your code is not good practice. Something like that should be embedded in a function, not directly in the main method.
Update - assembler output
For the code:
int a = 20;
int b = 66;

int t = a;
a = b;
b = t;

return a;

you get the assembler output:
movl    $20, -12(%rbp)
movl    $66, -8(%rbp)
movl    -12(%rbp), %eax
movl    %eax, -4(%rbp)
movl    -8(%rbp), %eax
movl    %eax, -12(%rbp)
movl    -4(%rbp), %eax
movl    %eax, -8(%rbp)
movl    -12(%rbp), %eax
popq    %rbp

For the code:
int a = 20;
int b = 66;

a ^= b ^= a ^= b;

return a;

you get
movl    $20, -8(%rbp)
movl    $66, -4(%rbp)
movl    -4(%rbp), %eax
xorl    %eax, -8(%rbp)
movl    -8(%rbp), %eax
xorl    %eax, -4(%rbp)
movl    -4(%rbp), %eax
xorl    %eax, -8(%rbp)
movl    -8(%rbp), %eax
popq    %rbp

What does that show?

It shows that both systems run in 12 instructions, including the copy to the stack (%rbp)
that both systems use the single register %eax
both systems use the stack as a temp store for the result (the XOR reuses -8 and -4 offsets in the stack, the tmp uses -12(%rbp)

Net result? Both systems use less than 16 bytes of the stack, they both use 1 register in addition to the stack, and they both have the same number of instructions.
I know which one is more readable....
Of course, with the above code, if I add -O2 to the optimization, I get the assembler:
movl    $66, %eax
ret

which, as you can imagine, is fast.