我知道strtol和strtof比atoi/atof更好,因为前者可以检测错误,而且strtol在处理非base-10时比atoi灵活得多。
但我仍然对一些东西感到好奇: OS X上的“man atoi”(或atof) (尽管不是在Linux上!)提到atoi/atof不是threadsafe。坦率地说,我很难想象atoi或atof的可能实现不是threadsafe。有人知道手册页为什么这么说吗?这些函数在OS或其他平台上真的不安全吗?如果是这样的话,为什么图书馆不直接用strtol来定义atoi,这样就是安全的?
发布于 2011-01-08 08:40:28
在做了一些研究之后,我认为这只是过去errno还是一个全局变量时的遗留问题。如果您选中从first revision开始的FreeBSD errno.h history,您会看到它最初定义为
extern int errno; /* global error number */现在它是一个函数。我真的想不出还有什么其他原因。
虽然atoi一直是strtol的包装器,但它也设置了errno,因此应该具有相同的线程安全性。这肯定只是一个文档问题。
发布于 2011-01-08 16:05:36
苹果libc中atoi()的Here's the implementation (atof()类似):
int
atoi(str)
const char *str;
{
return (int)strtol_l(str, (char **)NULL, 10, __current_locale());
}和strtol()
long
strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
{
return strtol_l(nptr, endptr, base, __current_locale());
}由于man strtol没有提到strtol()的线程安全问题,您可能会得出以下几个结论中的一个或多个:
atoi()是线程不安全的,strtol()也是线程不安全的,atoi()不保证线程安全,即使当前的实现恰好是线程安全的,<代码>H216<代码>H117他们过时了(我认为是错误的特例)<代码>H218<代码>F219__current_locale()返回一个指向描述线程区域设置的结构的指针(这并不奇怪)。但是,如果没有设置特定于线程的语言环境,__current_locale()将返回一个指向全局语言环境结构的指针。我认为处理全局变量可能是线程不安全的,但这个问题也适用于strtol()。
发布于 2013-03-27 22:11:35
这个答案是在这个问题被提出并首次得到回答的几年后。在我的Mac 10.8.3 (大约2013年3月)上,man atoi (或man atof)显示:
IMPLEMENTATION NOTES
The atof() and atof_l() functions are thread-safe and async-cancel-safe.
The atof() and atof_l() functions have been deprecated by strtod() and
strtod_l() and should not be used in new code.因此,最后一句话可能是,这里从来没有线程安全问题,只有文档中的错误。
https://stackoverflow.com/questions/4631310
复制相似问题