#365 Make strtod() conform to C99

closed-accepted
2008-05-15
2008-05-02
Ramiro Polla
No

Attached patch makes strtod() conform to C99.
It uses the already compiled-in strtod() implementation from gdtoa, and just aliases it from __strtod() to strtod().
The MSVCRT _strtod() function can still be accessed with the underscore.

Discussion

1 2 > >> (Page 1 of 2)
  • Ramiro Polla
    Ramiro Polla
    2008-05-02

     
    Attachments
  • Logged In: YES
    user_id=570619
    Originator: NO

    Your patch has been accepted and is now commited to CVS. You should expect to see it in the next release.

     
    • assigned_to: nobody --> ir0nh34d
    • status: open --> closed-accepted
     
  • Ramiro Polla
    Ramiro Polla
    2008-05-06

     
    Attachments
  • Ramiro Polla
    Ramiro Polla
    2008-05-06

    Logged In: YES
    user_id=488683
    Originator: YES

    As Danny Smith pointed out, MSVCRT doesn't have _strtod, so the last patch was wrong.
    New patch over latest CVS removes the alias from strtod to __strtod. It also edits stdlib.h to reflect to define strtod to __strtod when __NO_ISOCEXT is not set.
    File Added: fix_strtod.diff

     
  • Ramiro Polla
    Ramiro Polla
    2008-05-06

    • status: closed-accepted --> open-accepted
     
  • Logged In: YES
    user_id=570619
    Originator: NO

    Your patch has been accepted and is now commited to CVS. You should expect to see it in the next release.

     
    • status: open-accepted --> closed-accepted
     
  • Danny Smith
    Danny Smith
    2008-05-07

    Logged In: YES
    user_id=11494
    Originator: NO

    The latest patch breaks libstdc++.

    Unless we define __NO_ISOCEXT , strtod is only available as a preprocessor define.
    libstdc++ csttdlib will #undef strtod along with other std names so we get undefined references to std::strtod

    Danny

     
  • Ramiro Polla
    Ramiro Polla
    2008-05-07

    • status: closed-accepted --> open-accepted
     
  • Ramiro Polla
    Ramiro Polla
    2008-05-07

    Logged In: YES
    user_id=488683
    Originator: YES

    I must confess I never use C++. In fact, I don't even know how to test in which way this is broken.
    According to C99:
    7.1.2.6 Any declaration of a library function shall have external linkage.
    So I don't really know how to do that. __attribute__((alias)) doesn't work inside header files.
    Changing #define __strtod strtod to:
    static inline double __cdecl __MINGW_NOTHROW strtod (const char*nptr, char**endptr)
    { return __strtod(nptr, endptr); }
    works with and without -D__NO_ISOCEXT, and with #undef'ing strtod() in the source too.
    Any suggestions?

     
  • Ramiro Polla
    Ramiro Polla
    2008-05-08

     
    Attachments
  • Ramiro Polla
    Ramiro Polla
    2008-05-08

    Logged In: YES
    user_id=488683
    Originator: YES

    Here's a patch of my suggestion.
    Danny, can you please confirm if this is the right way to go? Or else what could be done.
    File Added: fix_strtod_again.diff

     
  • Danny Smith
    Danny Smith
    2008-05-08

    Logged In: YES
    user_id=11494
    Originator: NO

    Hello Ramira.

    As you quoted earlier for C++
    "7.1.2.6 Any declaration of a library function shall have external
    linkage."

    So, use C++ inline semantics with C++, and a simple define (or static inline if you prefer) for C

    #if !defined __NO_ISOCEXT /* in libmingwex.a */
    double __cdecl __MINGW_NOTHROW __strtod (const char * __restrict__ , char ** __restrict__ );
    #ifdef __cplusplus
    /* We require a function with with external linkage. */
    inline double __cdecl __MINGW_NOTHROW strtod (const char * __restrict__ __nptr,
    char ** __restrict__ __endptr)
    { return __strtod (__nptr, __endptr); }
    #else
    # define strtod __strtod
    #endif
    float __cdecl __MINGW_NOTHROW strtof (const char * __restrict__, char ** __restrict__);
    long double __cdecl __MINGW_NOTHROW strtold (const char * __restrict__, char ** __restrict__);
    #else /* __NO_ISOCEXT */

     
  • Ramiro Polla
    Ramiro Polla
    2008-05-08

    Logged In: YES
    user_id=488683
    Originator: YES

    That quote is from C99, not C++, so I guess there's no need for the #ifdef. Both C++ and C99 should have it.

     
  • Logged In: YES
    user_id=570619
    Originator: NO

    So where are we at with respect to a patch? As Danny pointed out, the last commit I did for this has broken things with C++. Would it be possible to get a newer patch that addresses the C++ issue?

     
  • Ramiro Polla
    Ramiro Polla
    2008-05-09

    Logged In: YES
    user_id=488683
    Originator: YES

    Danny, why did you drop the static keyword for C++?
    In C99, if two files that call strtod() are compiled with the static-less strtod() definition, the linker sees two implementations of the function, and fails.
    Can't the static also be used by C++?
    If not then a simple
    #ifndef __cplusplus
    static
    #endif
    inline ...
    should be fine.

     
  • Danny Smith
    Danny Smith
    2008-05-11

    Logged In: YES
    user_id=11494
    Originator: NO

    "Danny, why did you drop the static keyword for C++?"

    C++ std library functions need to have external linkage. C++ inlines do (they use linkonce semantics on mingw32 to avoid duplicate definitions).

    Danny

     
  • Logged In: YES
    user_id=570619
    Originator: NO

    Just to come to conclusion on this patch, is this appropriate:

    ===================================================================
    RCS file: /cvs/src/src/winsup/mingw/mingwex/gdtoa/strtodnrp.c,v
    retrieving revision 1.3
    diff -r1.3 strtodnrp.c
    39a40,51
    > #if !defined __NO_ISOCEXT /* in libmingwex.a */
    > double __cdecl __MINGW_NOTHROW __strtod (const char * __restrict__ , char ** __restrict__ );
    > #ifdef __cplusplus
    > /* We require a function with with external linkage. */
    > inline double __cdecl __MINGW_NOTHROW strtod (const char * __restrict__ __nptr, char ** __restrict__ __endptr)
    > { return __strtod (__nptr, __endptr); }
    > #else
    > # define strtod __strtod
    > #endif
    > float __cdecl __MINGW_NOTHROW strtof (const char * __restrict__, char **__restrict__);
    > long double __cdecl __MINGW_NOTHROW strtold (const char * __restrict__, char ** __restrict__);
    > #else /* __NO_ISOCEXT */
    45a58
    > #endif

     
  • Ramiro Polla
    Ramiro Polla
    2008-05-15

    Logged In: YES
    user_id=488683
    Originator: YES

    Sorry to take long to reply.
    Any of the 3 following should be good. Depending on the style you prefer.
    I personally prefer fix_strtod_again_5.diff

     
  • Ramiro Polla
    Ramiro Polla
    2008-05-15

     
  • Ramiro Polla
    Ramiro Polla
    2008-05-15

    Logged In: YES
    user_id=488683
    Originator: YES

    File Added: fix_strtod_again_3.diff

     
  • Ramiro Polla
    Ramiro Polla
    2008-05-15

     
  • Ramiro Polla
    Ramiro Polla
    2008-05-15

    Logged In: YES
    user_id=488683
    Originator: YES

    File Added: fix_strtod_again_4.diff

     
  • Ramiro Polla
    Ramiro Polla
    2008-05-15

     
1 2 > >> (Page 1 of 2)