Hi, Michael Gold wrote: > I was planning to use the c-strtod module in a library, but noticed some > problems when looking at its implementation. > ... > This is > not threadsafe because setlocale affects all threads in a program (and > also because setlocale doesn't seem to be threadsafe on all platforms). > The attached program demonstrates the problem -- if some thread calls > strtod while another is calling c_strtod, the call to strtod may return > an incorrect result in locales where the decimal point isn't '.'. > > c_strtod will also call abort() on these platforms if there's no memory > to copy the old locale string, which makes it inappropriate for use in > libraries. This should be documented in the function description.
The module 'c-strtod' is under GPL, not LGPL. This alone is enough of a hint that the function is not really usable in libraries. You can submit a patch for the function description. In the long run, however, if this function should be usable in libraries, I see two possible approaches: - Write a correct strtod() implementation - I mean, without rounding errors -, and add a 'char decimal_point' parameter. - Copy the argument string, preprocessing it by replacing the '.' with the locale dependent decimal-point character, and pass that to strtod(). > Finally, the documentation states c_strtod "operates as if the locale > encoding was ASCII", but the code doesn't actually convert the argument > from ASCII to the execution character set. We assume that the execution character set is a superset of the part of ASCII that matters for numbers (digits, basic Latin letters, dot, comma, plus, minus signs). > The first problem could probably be fixed by calling localeconv and > replacing '.' with the proper decimal point, which may require a > temporary memory allocation. Yes, nearly. Note that localeconv() is not multithread-safe either. Instead, we could use the function decimal_point_char() from lib/vasnprintf.c. Bruno