Hi Ben,
> 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?
Why does it conflict? gnulib's <stdlib.h> replacement already contains the
idiomatic solution. As you can see from m4/strtod.m4, there are three cases:
- function strtod ok
=> HAVE_STRTOD=1, REPLACE_STRTOD=0
- function strtod does not exist
=> HAVE_STRTOD=0, lib/strtod.c gets compiled
- function strtod does not obey C99
=> REPLACE_STRTOD=1, lib/strtod.c gets compiled
You are probably in the 3rd case? (Please look into your config.status to
confirm.)
The stdlib.in.h contains exactly the right idiom for these 3 cases:
#if @GNULIB_STRTOD@
/* Parse a double from STRING, updating ENDP if appropriate. */
# if @REPLACE_STRTOD@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define strtod rpl_strtod
# endif
_GL_FUNCDECL_RPL (strtod, double, (const char *str, char **endp)
_GL_ARG_NONNULL ((1)));
_GL_CXXALIAS_RPL (strtod, double, (const char *str, char **endp));
# else
# if !...@have_strtod@
_GL_FUNCDECL_SYS (strtod, double, (const char *str, char **endp)
_GL_ARG_NONNULL ((1)));
# endif
_GL_CXXALIAS_SYS (strtod, double, (const char *str, char **endp));
# endif
_GL_CXXALIASWARN (strtod);
...
In the 3rd case, you should see the
#define strtod rpl_strtod
and this #define should avoid a conflict between the function in the system
header and the function in gnulib.
> I'm appending my fix, which I have not yet pushed out.
You need first to analyze why the existing gnulib idiom did not work in this
situation. (Take a look at config.status and config.log. Look at the
"gcc -E -dD" output. And so on.)
Bruno