Anda di halaman 1dari 1

The Joy of

Programming S.G. Ganesh

Traps and Pitfalls: Swapping Two Variables—Part III


In May and June last year, we covered a few traps and pitfalls in trying to swap two variables without
using a temporary. This month, we’ll look at swapping variables without a temporary in a single
statement, and see how C and Java compilers treat them differently.

T
he following trick using three consecutive ex-or public static void main(String []s) {

operations for swapping two variables without int i = 3, j = 6;

using a temporary is well known and particularly System.out.println(“Before swap: i = “ + i + “ j = “ + j);

popular among students: i ^= (j ^= (i ^= j));


System.out.println(“After swap: i = “ + i + “ j = “ + j);

i ^= j; j ^= i; i ^= j; }
}

Here, i and j are integer variables and it works well


(we covered a few pitfalls earlier with this). For further The swap trick does not work! What happened? The
optimisation, one often sees this solution combining the Java specification (section 15.26.2) says: “The value of
three statements into a single statement: the left-hand side of a compound assignment is saved
before the right-hand side is evaluated”. In other words,
i ^= (j ^= (i ^= j)); the value of i and j are remembered and used for the
LHS values of i and j; so we do not get the values of i and
Try this with your favourite C compiler; it usually j swapped correctly.
works. This trick works based on the following To illustrate this, let us try the following: Pre-
assumption: the values of i and j are modified in the RHS compute the result of (i ^ j) and remember it in a
(right-hand side) of the expression and the modified temporary. Now use that temporary in the LHS instead
values are expected to be used in the LHS (left-hand side) of i; you’ll get the expected (correct) output of the
of the expression. swapped values of two variables:
However, this solution need not work and the updated
values of i and j need not get reflected when read class SwapTest {

again. This is because the compiler is free to optimise public static void main(String []s) {

the sequence of reads and writes, using temporaries int i = 3, j = 6;

internally. This problem is covered by an intricate and int cache = (i ^ j);

difficult to understand technical issue known as ‘sequence System.out.println(“Before swap: i = “ + i + “ j = “ + j);

points’ (see en.wikipedia.org/wiki/Sequence_point). For cache ^= (j ^= (i ^= j));

example, if the initial value of i is 0, after executing the i = cache;

statement i=i++, i might be 0 or 1: it is implementation System.out.println(“After swap: i = “ + i + “ j = “ + j);

defined behaviour. For the same reason, the expression i }

^= (j ^= (i ^= j)) need not swap the two variables i and j }

correctly—it depends on the compiler as to what we’ll get


as values for i and j. It works, right?
We’ll take a different approach in this column Well, don’t worry if you feel that the explanation for the
and cover Java to understand the implications of Java programs is not clear. Next month, we’ll dig deeper by
such statements. Unlike C, Java does not have code looking at the byte codes generated for the swap code and
segments leading to implementation defined behaviour understand how it works.
(i.e., the programs written in Java will behave the
same way, irrespective of the Java compiler used). For S.G. Ganesh is a research engineer in Siemens (Corporate
the swap in a single statement case, let us see what Technology), Bangalore. His latest book is “60 Tips on
happens in Java: Object Oriented Programming” (ISBN 978-0-07-065670-3),
published by Tata McGraw-Hill, New Delhi. You can reach
class Swap {
him at sgganesh@gmail.com

102 june 2008 | LINUX For You | www.openITis.com

Anda mungkin juga menyukai