chiark / gitweb /
work around stupid qsort_r BSD/GNU incompatibility
authorstevenj <stevenj@alum.mit.edu>
Thu, 29 Oct 2009 00:53:22 +0000 (20:53 -0400)
committerstevenj <stevenj@alum.mit.edu>
Thu, 29 Oct 2009 00:53:22 +0000 (20:53 -0400)
darcs-hash:20091029005322-c8de0-bc99d7ce1efdc63f5b29848d2e49c46ace31a1f4.gz

NEWS
util/qsort_r.c

diff --git a/NEWS b/NEWS
index 9acbdcfae08cc2d56d7a57bafb96007c5e34d7df..a6af2d631b8e21493421179875e6de4c687193ed 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+NLopt 1.1
+
+* Workaround for incompatible qsort_r functions in BSD and GNU libc
+  by always using my own version; thanks to Wendy Vandoolaeghe
+  and Philippe Preux for the bug report and explanation.
+
 * Workaround for gcc 3.4.x conflict with HUGE_VAL definition in Solaris
   (gcc bug 19933).
 
index ebbc649d4a2eef45c9c99f8a5685996421057bba..1bbeecedaddc051fca629b1b051a1a393e75cdaa 100644 (file)
 #include "nlopt-util.h"
 
 /* Simple replacement for the BSD qsort_r function (re-entrant sorting),
-   if it is not available.  (It looks like glibc 2.8 will include qsort_r
-   as well.) 
+   if it is not available.
+
+   (glibc 2.8 included a qsort_r function as well, but totally
+   *%&$#-ed things up by gratuitously changing the argument order, in
+   such a way as to allow code using the BSD ordering to compile but
+   die a flaming death at runtime.  Damn them all to Hell, I'll just
+   use my own implementation.)
 
    (Actually, with glibc 2.3.6 on my Intel Core Duo, my implementation
-   below seems to be significantly faster than qsort.  Go figure.
-   Even so, I'd rather use the libc version of qsort_r if it is available,
-   on general principles, and to reduce code bloat.) */
+   below seems to be significantly faster than qsort.  Go figure.)
+*/
 
-#ifndef HAVE_QSORT_R
+#ifndef HAVE_QSORT_R_damn_it_use_my_own
 /* swap size bytes between a_ and b_ */
 static void swap(void *a_, void *b_, size_t size)
 {
@@ -63,7 +67,11 @@ static void swap(void *a_, void *b_, size_t size)
 void nlopt_qsort_r(void *base_, size_t nmemb, size_t size, void *thunk,
                   int (*compar)(void *, const void *, const void *))
 {
-#ifdef HAVE_QSORT_R
+#ifdef HAVE_QSORT_R_damn_it_use_my_own
+     /* Even if we could detect glibc vs. BSD by appropriate
+       macrology, there is no way to make the calls compatible
+       without writing a wrapper for the compar function...screw
+       this. */
      qsort_r(base_, nmemb, size, thunk, compar);
 #else
      char *base = (char *) base_;