You are on page 1of 1

The Joy of

Programming
C Traps and Pitfalls:
Swapping Two Variables–Part II S.G. GANESH

Let us look at the interesting problem of swapping two variables without using any temporary
variables. We will discover the possible pitfalls of using smart ‘tricks’ to solve the problem. This
column is to help students and novices understand C better.

I
n my previous column, we saw some of the pitfalls of using either of the bits is set, the result is true, and if both bits are
+ and – operators to swap two variables without using a same, the result is false)...it’s indeed a curious operator!
temporary variable: Bitwise operations are only for integral values; so this
swapping trick cannot be used for floating-point numbers.
*i = *i + *j; None of the tricks we discussed will work well for swapping
*j = *i - *j; two pointers. Other than binary -, no other binary arithmetic
*i = *i - *j; operators (+, *, /, %) can be used for two pointers. A pointer
represents the address and subtracting two addresses is
Think about the logic in using + and – for such acceptable (to see the offset or difference between the two
GUEST COLUMN

swapping. Can we use any other operators for a locations, for example, in an array), and using other arithmetic
similar purpose? Yes, * and / are complementary operators with two pointers will result in compiler error. Also, it
operators and they can be used for such swapping as is incorrect to apply ^ on two pointers. You can cast the
well, following the same logic: operands to integers and apply ^, but it’s a bad approach for
many reasons. For example, the conversion would fail if the
*i = *i * *j; pointer and integer sizes are different.
*j = *i / *j; For practical uses, it is best to stick to the plain and straight-
*i = *i / *j; forward approach of using a temporary variable for swapping.

It works. However, this solution has two Find the bug


problems: if i and j are big, then *i * *j will overflow Here is a swap function for swapping two strings:
and by using the division operation you can’t get the
original values back; and if *j is 0, the *i / *j void swapStr(char *i, char *j){
expression will result in a divide by zero exception. char *temp = i;
What about the two complementary bit-wise i = j;
operators & and | ...can we use them for swapping by j = temp;
following similar logic? }

*i = *i & *j; Looks fine and comfortable, doesn’t it? But it does not work:
*j = *i | *j;
*i = *i | *j; char *i = “first”;
char *j = “second”;
No, it doesn’t work. Unlike + and *, the & operator is not printf(“Before swap : %s %s\n”, i, j);
really an operator that retains (or accumulates) both the values swapStr(i, j);
in some form that using | twice could retrieve. Try it once to printf(“After swap : %s %s\n”, i, j);
confirm it yourself. // output:
However, the bitwise ^ can fit the requirement (though it // Before swap : first second
doesn’t have a complementary operator like + and –, * and / // After swap : first second
operators):
Can you find what went wrong?
*i = *i ^ *j;
*j = *i ^ *j; S G Ganesh is an engineer in Hewlett-Packard’s C++
*i = *i ^ *j; compiler team. He is a member of the ANSI/ISO C++
Standardisation committee (JTC1/SC22/WG21). You can
It works because the ^ operator complements itself (if reach him at sgganesh@gmail.com.

www.linuxforu.com | LINUX FOR YOU | JUNE 2007 87

CMYK