Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does OSX document atoi/atof as not being threadsafe?

Tags:

c

macos

I understand that strtol and strtof are preferred to atoi/atof, since the former detect errors, and also strtol is much more flexible than atoi when it comes to non-base-10.

But I'm still curious about something: 'man atoi' (or atof) on OS X (though not on Linux!) mentions that atoi/atof are not threadsafe. I frankly have a hard time imagining a possible implementation of atoi or atof that would not be threadsafe. Does anybody know why the man page says this? Are these functions actually unsafe on OS X or any other platform? And if they are, why on earth wouldn't the library just define atoi in terms of strtol, and therefore be safe?

like image 240
Larry Gritz Avatar asked Jan 07 '11 23:01

Larry Gritz


People also ask

Why is atoi deprecated?

The atof () , atoi () , atol () , and atoll () functions are obsolescent because the strtod () , strtof () , strtol () , strtold () , strtoll () , strtoul () , and strtoull () functions can emulate their usage and have more robust error handling capabilities.

Why atoi is not safe?

* The atoi function is not thread-safe and also not async-cancel safe. * The atoi function has been deprecated by strtol and should not be used in new code.

Is ATOF safe?

The atof() function is not thread-safe and also not async-cancel-safe. The atof() function has been deprecated by strtod() and should not be used in new code.


1 Answers

Taking a look at the manual page on MacOS X 10.6.6, it documents two functions, atof() and atof_l(), and I suspect that gives a hint as to why the function is deemed not thread-safe:

SYNOPSIS

#include <stdlib.h>
double atof(const char *str);

#include <xlocale.h>
double atof_l(const char *str, locale_t loc);

DESCRIPTION

The atof() function converts the initial portion of the string pointed to by str to double representation.

It is equivalent to:

      strtod(str, (char **)NULL);

The decimal point character is defined in the program's locale (category LC_NUMERIC).

While the atof() function uses the current locale, the atof_l() function may be passed a locale directly. See xlocale(3) for more information.

IMPLEMENTATION NOTES

The atof() function is not thread-safe and also not async-cancel-safe.

The atof() function has been deprecated by strtod() and should not be used in new code.

ERRORS

The function atof() need not affect the value of errno on an error.

My suspicion is that if the current locale is changed by another thread while the atof() function is executing, the result is not guaranteed. Otherwise, there seems to be no reason for the warning.


I've poked around for a definitive location of the Darwin C library source code, but have not found one. If you go to the FreeBSD source code for atoi(), it is clear that the function implementation is trivial:

int
atoi(str)
    const char *str;
{
    return (int)strtol(str, (char **)NULL, 10);
}

(Yes, not even using a prototyped definition!)

The man page for strtol() does not have the weasel wording about thread safety or async-cancel safety. However, a quick look at the source code for strtol() shows that it uses isspace(), which is affected by locale:

ISO/IEC 9899:1999, Section 7.11.1.1 The setlocale function

187 The only functions in 7.4 whose behavior is not affected by the current locale are isdigit and isxdigit.

(Where §7.4 is for <ctype.h>.)

Now, while I'm not sure that this code is identical to what's in Darwin (MacOS X), it is likely to be similar. I think that there could be room for errata in the man pages - it is not so clear whether the page that needs correction is the one for atoi() or the one for strtol().

like image 66
Jonathan Leffler Avatar answered Sep 25 '22 01:09

Jonathan Leffler