Re: Double linked list with one pointer

From: "Dann Corbit" <DCorbit(at)connx(dot)com>
To: "Bruce Momjian" <pgman(at)candle(dot)pha(dot)pa(dot)us>, "Gaetano Mendola" <mendola(at)bigfoot(dot)com>
Cc: <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Double linked list with one pointer
Date: 2003-12-07 01:28:07
Message-ID: D90A5A6C612A39408103E6ECDD77B829408C98@voyager.corporate.connx.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

> -----Original Message-----
> From: Bruce Momjian [mailto:pgman(at)candle(dot)pha(dot)pa(dot)us]
> Sent: Saturday, December 06, 2003 5:02 PM
> To: Gaetano Mendola
> Cc: pgsql-hackers(at)postgresql(dot)org
> Subject: Re: [HACKERS] Double linked list with one pointer
>
>
> Gaetano Mendola wrote:
> > If I'm not wrong Neil Conway is working on
> > reimplement a double linked list.
> > Looking around I found this post of
> > "Herb Sutter" on comp.lang.c++:
> >
> >
> ======================================================================
> > ==
> > In particular, a motivation behind two-way pointers is that you
> > can have a more space-efficient doubly linked list if you
> store only one
> > (not two) pointer's worth of storage in each node. But how
> can the list
> > still be traversable in both directions? The idea is that each node
> > stores, not a pointer to one other node, but a pointer to
> the previous
> > node XOR'd with a pointer to the next node. To traverse the
> list in either
> > direction, at each node you get a pointer to the next node by simply
> > XORing the current node's two-way pointer value with the
> address of the
> > last node you visited, which yields the address of the next
> node you want
> > to visit. For more details, see:
> >
> > "Running Circles Round You, Logically"
> > by Steve Dewhurst
> > C/C++ Users Journal (20, 6), June 2002
> >
> > I don't think the article is available online, alas, but
> you can find
> > some related source code demonstrating the technique at:
> >
> > http://www.semantics.org/tyr/tyr0_5/list.h
>
> That certainly is an amazing idea. You know the pointer you
> are coming from so you can XOR to find the next pointer.
>
> I agree with a Tom that we don't have much use for
> double-link lists, but is a nice idea.

Except when it causes undefined behavior. The subtraction trick also
suffers from the same evil flaw.

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=SErn
3.289%24O17.9552%40client&rnum=3&prev=/groups%3Fq%3Dxor%2Bhack%2Bgroup:c
omp.lang.c.*%2Bauthor:corbit%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8
%26selm%3DSErn3.289%2524O17.9552%2540client%26rnum%3D3

From the C-FAQ:

3.3b: Here's a slick expression:

a ^= b ^= a ^= b

It swaps a and b without using a temporary.

A: Not portably, it doesn't. It attempts to modify the variable a
twice between sequence points, so its behavior is undefined.

For example, it has been reported that when given the code

int a = 123, b = 7654;
a ^= b ^= a ^= b;

the SCO Optimizing C compiler (icc) sets b to 123 and a to 0.

See also questions 3.1, 3.8, 10.3, and 20.15c.

10.3: How can I write a generic macro to swap two values?

A: There is no good answer to this question. If the values are
integers, a well-known trick using exclusive-OR could perhaps
be used, but it will not work for floating-point values or
pointers, or if the two values are the same variable. (See
questions 3.3b and 20.15c.) If the macro is intended to be
used on values of arbitrary type (the usual goal), it cannot
use a temporary, since it does not know what type of temporary
it needs (and would have a hard time picking a name for it if
it did), and standard C does not provide a typeof operator.

The best all-around solution is probably to forget about using a
macro, unless you're willing to pass in the type as a third
argument.

20.15c: How can I swap two values without using a temporary?

A: The standard hoary old assembly language programmer's trick is:

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

But this sort of code has little place in modern, HLL
programming. Temporary variables are essentially free,
and the idiomatic code using three assignments, namely

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

is not only clearer to the human reader, it is more likely to be
recognized by the compiler and turned into the most-efficient
code (e.g. using a swap instruction, if available). The latter
code is obviously also amenable to use with pointers and
floating-point values, unlike the XOR trick. See also questions
3.3b and 10.3.

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2003-12-07 01:29:04 Re: 7.4.1 ... slight change of scheduale ...
Previous Message Bruce Momjian 2003-12-07 01:06:56 Re: 7.4.1 ... slight change of scheduale ...