bug-gnulib
[Top][All Lists]
Advanced

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

[PATCH] bypass broken inline strtod() definition in <stdlib.h> on Mingw


From: Ben Pfaff
Subject: [PATCH] bypass broken inline strtod() definition in <stdlib.h> on Mingw
Date: Thu, 10 Jun 2010 21:17:40 -0700
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux)

Cross-compiling lib/strtod.c failed on Mingw, as reported at
http://savannah.gnu.org/bugs/?29965:

    strtod.c:37: error: redefinition of 'strtod'
    /usr/i686-pc-mingw32/sys-root/mingw/include/stdlib.h:319: note:
    previous definition of 'strtod' was here 

The problem was the section of stdlib.h cited in the above
message:

    double __cdecl __MINGW_NOTHROW __strtod (const char*, char**);
    #ifdef __cplusplus
    /* We require a function with external linkage. */
    #else
    static
    #endif /* Not __cplusplus */
    __inline__ double __cdecl __MINGW_NOTHROW
    strtod (const char* __restrict__ __nptr, char** __restrict__ __endptr)
    {
      return __strtod(__nptr, __endptr);
    }
    float __cdecl __MINGW_NOTHROW strtof (const char * __restrict__, char ** 
__restrict__);
    long double __cdecl __MINGW_NOTHROW strtold (const char * __restrict__, 
char ** __restrict__);

As you can see, this defines an inline version of strtod() that
conflicts with the out-of-line version in lib/strtod.c.

Is there an idiomatic solution for this kind of problem?  It is
the first time that I have run into this particular form of
brokenness before.

I'm appending my fix, which I have not yet pushed out.

--8<--------------------------cut here-------------------------->8--

>From 525a69cbe8d636ac1442aab4c6adb8df09b4b534 Mon Sep 17 00:00:00 2001
From: Ben Pfaff <address@hidden>
Date: Thu, 10 Jun 2010 21:10:51 -0700
Subject: [PATCH] Bypass broken inline strtod() definition in <stdlib.h> on 
Mingw.

* m4/strtod.m4: Detect broken inline strtod().
* lib/stdlib.in.h: Bypass broken inline strtod().
---
 lib/stdlib.in.h |   11 +++++++++++
 m4/strtod.m4    |   37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index d74c251..e982fea 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -29,9 +29,20 @@
 
 #ifndef _GL_STDLIB_H
 
+#ifdef HAVE_BROKEN_INLINE_STRTOD_DEFINITION
+/* strtod() is broken and must be replaced, but <stdlib.h> defines a inline
+   strtod() that ordinarily prevents it from being replaced, so we must use a
+   macro to rename it temporarily. */
+#define strtod _gl_broken_inline_strtod
+#endif
+
 /* The include_next requires a split double-inclusion guard.  */
 address@hidden@ @NEXT_STDLIB_H@
 
+#ifdef HAVE_BROKEN_INLINE_STRTOD_DEFINITION
+#undef strtod
+#endif
+
 #ifndef _GL_STDLIB_H
 #define _GL_STDLIB_H
 
diff --git a/m4/strtod.m4 b/m4/strtod.m4
index 4cccb6d..47597be 100644
--- a/m4/strtod.m4
+++ b/m4/strtod.m4
@@ -82,6 +82,43 @@ numeric_equal (double x, double y)
       _AC_LIBOBJ_STRTOD
     fi
   fi
+
+  if test "$gl_cv_func_strtod_works" != yes; then
+    dnl Mingw defines an inline version of strtod() in <stdlib.h>,
+    dnl which prevents replacing it unless we #define strtod to
+    dnl something else before including <stdlib.h> and then #undef
+    dnl it afterward.
+    AC_CACHE_CHECK([whether strtod may safely be defined],
+                   [gl_cv_func_strtod_may_define],
+                  [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <stdlib.h>
+double strtod (const char *nptr, char **endptr)
+{
+}
+]])],
+                  [gl_cv_func_strtod_may_define=yes],
+                  [gl_cv_func_strtod_may_define=no])])
+    if test $gl_cv_func_strtod_may_define = no; then
+      AC_CACHE_CHECK([whether strtod may be moved aside and defined],
+                    [gl_cv_func_strtod_move_aside],
+                    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#define strtod busted_strtod
+#include <stdlib.h>
+#undef strtod
+double strtod (const char *nptr, char **endptr)
+{
+}
+]])],
+                    [gl_cv_func_strtod_move_aside=yes],
+                    [gl_cv_func_strtod_move_aside=no])])
+      if test $gl_cv_func_strtod_move_aside = yes; then
+        AC_DEFINE([HAVE_BROKEN_INLINE_STRTOD_DEFINITION], [1],
+                  [Define to 1 if a broken strtod() must be replaced, but
+                   <stdlib.h> defines a inline strtod() that ordinarily
+                  prevents it from being replaced.])
+      fi
+    fi
+  fi
 ])
 
 # Prerequisites of lib/strtod.c.
-- 
1.7.1


-- 
Ben Pfaff 
http://benpfaff.org



reply via email to

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