bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug-gnulib] [bug-gnulib] fts portability fix for hosts with unusual


From: Paul Eggert
Subject: Re: [bug-gnulib] [bug-gnulib] fts portability fix for hosts with unusual pointer semantics
Date: Mon, 09 May 2005 17:12:54 -0700
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.4 (gnu/linux)

Bruno Haible <address@hidden> writes:

> (I have not yet seen any platform where the ABI treats 'void *' pointers
> differently than any data pointers. The basic reason that 'void *' exists
> at all in C is to permit this kind of cast.)

The basic problem, as I understand it, is that some architectures
distinguish between word pointers and byte pointers; the latter are
larger, and void * therefore is larger than (say) int *.  The code in
question assumes that void * has the same representation as word
pointers, but this isn't correct in general.

Affected architectures include Prime, Eclipse MV, classic HP 3000.
The classic HP 3000 is barely alive (HP support ends 2006-12-31,
according to <http://www.robelle.com/library/smugbook/classic.html>).
Perhaps some other machines are affected; I don't know.  I wouldn't be
hugely surprised if it affects some x86 hosts (due to the large-
versus small-pointer problem in both the 16-32 and 32-64 transitions).

> Therefore I would conditionalize this extra function indirection with
> #ifdef PREFER_RUNTIME_OVERHEAD_OVER_CAST
> or similar, so that it is disabled by default.

Good point, but I'd rather enable it automatically if possible.  I
installed this instead into coreutils; I hope it is a reasonable
heuristic.

2005-05-09  Paul Eggert  <address@hidden>

        * lib/fts.c (fts_sort): Optimize the common case where all pointers
        smell the same.

--- lib/fts.c   9 May 2005 18:53:33 -0000       1.25
+++ lib/fts.c   9 May 2005 23:54:26 -0000       1.26
@@ -1240,6 +1240,20 @@ fts_sort (FTS *sp, FTSENT *head, registe
 {
        register FTSENT **ap, *p;
 
+       /* On most modern hosts, void * and FTSENT ** have the same
+          run-time representation, and one can convert sp->fts_compar to
+          the type qsort expects without problem.  Use the heuristic that
+          this is OK if the two pointer types are the same size, and if
+          converting FTSENT ** to long int is the same as converting
+          FTSENT ** to void * and then to long int.  This heuristic isn't
+          valid in general but we don't know of any counterexamples.  */
+       FTSENT *dummy;
+       int (*compare) (void const *, void const *) =
+         ((sizeof &dummy == sizeof (void *)
+           && (long int) &dummy == (long int) (void *) &dummy)
+          ? (int (*) (void const *, void const *)) sp->fts_compar
+          : fts_compar);
+
        /*
         * Construct an array of pointers to the structures and call qsort(3).
         * Reassemble the array in the order returned by qsort.  If unable to
@@ -1263,7 +1277,7 @@ fts_sort (FTS *sp, FTSENT *head, registe
        }
        for (ap = sp->fts_array, p = head; p; p = p->fts_link)
                *ap++ = p;
-       qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), fts_compar);
+       qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), compare);
        for (head = *(ap = sp->fts_array); --nitems; ++ap)
                ap[0]->fts_link = ap[1];
        ap[0]->fts_link = NULL;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]