Swaping?

A

Andry

Hi,
Is there any way in C++ swap two values without using temp("third
variable").if yes thne how we can ?
 
R

Rolf Magnus

Andry said:
Hi,
Is there any way in C++ swap two values without using temp("third
variable").

Yes, but don't bother. It usually has no advantage over using a temporary
variable. The best is to use the std::swap function.
 
J

jkherciueh

Tomás Ó hÉilidhe said:
a ^= b;
b ^= a;
a ^= b;

Just as a word of caution, this snippet fails to swap in this context:

int x = 5;
int& a = x;
int& b = x;

a ^= b;
b ^= a;
a ^= b;

In particular, it is not suitable for implementing a swap function for int.


Best

Kai-Uwe Bux
 
T

Tomás Ó hÉilidhe

Nope, he said values, not just values of integer type, and the above
does not apply to values of user defined types.


Wups, I should have realised I was in comp.lang.c++ rather than
comp.lang.c.

There's a "swap" function in C++ which is used for swapping objects.
 
R

Ron Natalie

Tomás Ó hÉilidhe said:
a ^= b;
b ^= a;
a ^= b;
Once again we are in the inane stupidity of premature optimization.

The C++ answer is yes, you use std::swap:

swap(a,b)

The computer answer in general, is that XOR is usually LESS
efficient than using a temporary. In many cases even
doing the XOR trick involves using temporary registers
on processors that can't XOR memory locations directly.
In which case the entire thing becomes subterfuge as

{
int t = a;
a = b;
b = t;
}

ends up not consuming any specific memory:

LD R1, a
LD R2, b
ST R1, b
ST R2, a

rather than

LD R1, a
LD R2, b
XOR R1,R1,R2
XOR R2,R2,R1
XOR R1,R1,R2
ST R1, a
ST R2, b


Further, once you get into classes rather than integers, swap
may be much more highly optimized than copying to a temporary
(and obviously most classes don't handle XOR).
 
T

Tomás Ó hÉilidhe

Once again we are in the inane stupidity of premature optimization.



There's nothing "prematuring optimising" about using one method over
another because it's more efficient.

I'm not saying that the XOR method is more efficient than the "temporary"
method, but if it were, it would make perfect sense to use it if you want
an efficient program.
 
E

Erik Wikström

There's nothing "prematuring optimising" about using one method over
another because it's more efficient.

In general no, if there are several ways to do something there is
nothing wrong with using the most efficient one, *unless* the most
efficient one also obscures the intent of the code. Code should be
written with clarity and correctness as primary goal, when you have
clear and correct working code you can, if necessary, start using less
obvious constructs to make it more efficient.
 
T

Tomás Ó hÉilidhe

In general no, if there are several ways to do something there is
nothing wrong with using the most efficient one, *unless* the most
efficient one also obscures the intent of the code. Code should be
written with clarity and correctness as primary goal, when you have
clear and correct working code you can, if necessary, start using less
obvious constructs to make it more efficient.


The language has comments for a reason. If the following is really too
obscure:

a ^= b;
b ^= a;
a ^= b;

, then replace it with:


a ^= b; /* Method for swapping */
b ^= a; /* the values of two */
a ^= b; /* integer types. */

If a programmer shies away from using code just because they can't
understand it at first glance, then I'd doubt the competentancy of that
programmer.

Of course there's business firms out there that have a policy of "the
dumber the better", but that doesn't mean the entire C++ developer
community should be watered down by it.
 
E

Erik Wikström

The language has comments for a reason. If the following is really too
obscure:

a ^= b;
b ^= a;
a ^= b;

, then replace it with:


a ^= b; /* Method for swapping */
b ^= a; /* the values of two */
a ^= b; /* integer types. */

It is not only other programmers that will read your code, the compiler
will also try to interpret what you want to do. In the old days when
compilers were not as good at optimising as they are today a number of
tricks were invented to make code faster. As Ron Natalie pointed out
using XOR might actually be slower because a compiler might not be smart
enough to figure out what the final results of XORing will be, but when
using a temporary the compiler can. Of couse, one should always measure
to be sure.
 
P

Pete Becker

The language has comments for a reason. If the following is really too
obscure:

a ^= b;
b ^= a;
a ^= b;

, then replace it with:


a ^= b; /* Method for swapping */
b ^= a; /* the values of two */
a ^= b; /* integer types. */

But the comment is wrong. First, the code doesn't swap the values of
two integer types, it swaps the values of two integers. Second, it
doesn't always swap the values of two integers, as has been pointed out
elsewhere. So the comment should probably be "Method for swapping the
values of two integers, or maybe setting them to zero".
 
J

jkherciueh

Tomás Ó hÉilidhe said:
The language has comments for a reason. If the following is really too
obscure:

a ^= b;
b ^= a;
a ^= b;

, then replace it with:


a ^= b; /* Method for swapping */
b ^= a; /* the values of two */
a ^= b; /* integer types. */

Your comment is very misleading. You should at least write:

a ^= b; // Method for swapping the
b ^= a; // values of two integers
a ^= b; //
// WARNING: this code is only
// correct when
// &a != &b or a == 0
// so don't lift this code and
// use it in an overload of
// swap for int.
//
// RATIONALE: we use this code
// here instead of std::swap
// because ...

Without the warning, the snippet is dangerous since the code might be
reused; and without the rationale section, any competent maintenance
programmer will replace the snippet by swap(a,b) on first sight.

If a programmer shies away from using code just because they can't
understand it at first glance, then I'd doubt the competentancy of that
programmer.

Of course there's business firms out there that have a policy of "the
dumber the better", but that doesn't mean the entire C++ developer
community should be watered down by it.

There seems to be an assumption here that

a ^= b;
b ^= a;
a ^= b;

is smarter than the "watered down" version

swap( a, b );

I wonder how you came to that conclusion. Is there any advantage of the
obscure 3 line version compared to the self-documenting one-liner? I fail
to see it.

Also for the more general point: choosing the harder to understand over the
equivalent easy is poor style; and since it creates maintenance costs it
needs to be justified by gains somewhere else that offset the costs.


Best

Kai-Uwe Bux
 
P

Pete Becker

There seems to be an assumption here that

a ^= b;
b ^= a;
a ^= b;

is smarter than the "watered down" version

swap( a, b );

I wonder how you came to that conclusion.

Not smarter, but cleverer. Just like doing template metaprogramming to
fix edge cases that don't need to be fixed.
 
T

Tomás Ó hÉilidhe

I've gotten a few replies so I'll reply to them all at once.

Regarding the XOR method, I myself wouldn't use it.

My argument wasn't about the XOR method in particular, but rather about
shying away from using more efficient constructs simply because there's
less efficient, simpler solutions. (And again, I did not suggest nor am
I suggesting that the XOR method is more efficient than a canonical
swap).

If, and it's a huge IF -- a hypothetical even -- the XOR method were to
be faster than a canonical swap, I would use it if I wanted optimal
efficiency in my code. I wouldn't shy away from it just because it looks
cryptic at first glance. Even make a macro or inline function out of it
and document it if you want to use it considerably in your code.

I'd love to give a great example of cryptic-looking code that I'd
actually use... but I can't really think of any. I'd bitshift instead of
multiplying or dividing by a power of two... but that's not really
cryptic.

Are things considered cryptic if they're hidden away in a macro? Is the
following cryptic?

SWAP_INTS(a,b);

The only thing I am against is the phobia of using efficient constructs
that are a little more complicated than their less efficient
counterparts. Of course, there are times I have gone for elegancy
instead of efficiency (especially when it comes to designing abstract
base classes as interfaces), but if I'm writing an algorithm then you
can be sure I won't be programming in the manner in which old women
drive.

Take an operating system like Windows XP... how much faster do you think
it would run if the programmers didn't go for the easiest solution every
time? Actually that's a bad example; Windows XP wouldn't run at all if
they went for the easist solution every time because Microsoft
programmers are mostly incompetant. But pretending for the moment that
they can program competantly, how much faster do you think it would run?
I'd say maybe 15% or 20% faster.
 
B

Bo Persson

Tomás Ó hÉilidhe said:
I've gotten a few replies so I'll reply to them all at once.

Regarding the XOR method, I myself wouldn't use it.

My argument wasn't about the XOR method in particular, but rather
about shying away from using more efficient constructs simply
because there's less efficient, simpler solutions. (And again, I
did not suggest nor am I suggesting that the XOR method is more
efficient than a canonical swap).

If, and it's a huge IF -- a hypothetical even -- the XOR method
were to be faster than a canonical swap, I would use it if I wanted
optimal efficiency in my code. I wouldn't shy away from it just
because it looks cryptic at first glance. Even make a macro or
inline function out of it and document it if you want to use it
considerably in your code.

I think the real counter argument is that IF the xor version were
actually faster (and correct :), the std::swap implementation would
already use it.


Bo Persson
 
T

Tomás Ó hÉilidhe

But the comment is wrong. First, the code doesn't swap the values of
two integer types, it swaps the values of two integers. Second, it
doesn't always swap the values of two integers, as has been pointed out
elsewhere. So the comment should probably be "Method for swapping the
values of two integers, or maybe setting them to zero".


Do you find something ambiguous in "swap the values of two integer
types"? Were you under the mistaken belief that a type could have a value?
I can't think of any other meanings that can be taken from it (either
correct or otherwise).
 
J

James Kanze

Wups, I should have realised I was in comp.lang.c++ rather than
comp.lang.c.

Even in comp.lang.c, it doesn't work. It fails for all non
integer types (e.g. floating point, pointers, structs...), and
it fails if a and b refer to the same object.
There's a "swap" function in C++ which is used for swapping
objects.

Which is generally the preferred method, because it will have
been specialized if there is some special way of swapping more
rapidly.
 
P

Pete Becker

Do you find something ambiguous in "swap the values of two integer
types"?

No. It's not ambiguous. It's simply wrong.
Were you under the mistaken belief that a type could have a value?
No.

I can't think of any other meanings that can be taken from it (either
correct or otherwise).

This isn't hard: you can't swap the values of types, so claiming that
that's what the code does is wrong.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top