我知道strtol和strtof比atoi/atof更受欢迎,因为前者检测错误,而且当涉及非base-10时,strtol比atoi更灵活.
但我仍然对某些事情感到好奇:OS X上的'man atoi'(或atof)(虽然不在Linux上!)提到atoi/atof不是线程安全的.坦率地说,我很难想象atoi或atof的可能实现是不是线程安全的.有人知道为什么手册页会这么说吗?这些功能在OS X或任何其他平台上实际上是不安全的吗?如果它们是,那么为什么图书馆不会根据strtol定义atoi,因此是安全的?
看一下 MacOS X 10.6.6 上的手册页,它记录了两个函数atof()和atof_l(),我怀疑这给出了为什么该函数被认为不是线程安全的提示:
\n\n概要
\nRun Code Online (Sandbox Code Playgroud)\n#include <stdlib.h>\ndouble atof(const char *str);\n\n#include <xlocale.h>\ndouble atof_l(const char *str, locale_t loc);\n描述
\n该
\natof()函数将 str 指向的字符串的初始部分转换为双精度表示形式。它相当于:
\nRun Code Online (Sandbox Code Playgroud)\nstrtod(str, (char **)NULL);\n小数点字符在程序的区域设置(类别 LC_NUMERIC)中定义。
\n当
\natof()函数使用当前区域设置时,atof_l()可以直接向函数传递区域设置。有关详细信息,请参阅 xlocale(3)。实施说明
\n该
\natof()函数不是线程安全的,也不是异步取消安全的。该
\natof()函数已被弃用strtod(),不应在新代码中使用。错误
\n该函数不需要影响错误时
\natof()的值。errno
我的怀疑是,如果在函数执行时当前区域设置被另一个线程更改atof(),则无法保证结果。否则,似乎没有理由发出警告。
我已经四处寻找 Darwin C 库源代码的明确位置,但还没有找到。如果您查看 FreeBSD 的源代码atoi(),很明显该函数的实现是微不足道的:
int\natoi(str)\n const char *str;\n{\n return (int)strtol(str, (char **)NULL, 10);\n}\nRun Code Online (Sandbox Code Playgroud)\n(是的,甚至没有使用原型定义!)
\n的手册页strtol()没有关于线程安全或异步取消安全的狡猾措辞。然而,快速浏览一下 的源代码就会strtol()发现它使用了isspace(),它受区域设置的影响:
ISO/IEC 9899:1999,第 7.11.1.1 节 setlocale 函数
\n\n\n187 7.4 中唯一其行为不受当前语言环境影响的函数是 isdigit 和 isxdigit。
\n
(其中 \xc2\xa77.4 代表<ctype.h>。)
现在,虽然我不确定这段代码是否与 Darwin (MacOS X) 中的代码相同,但它很可能是相似的。我认为手册页中可能有勘误的空间 - 目前还不清楚需要更正的页面是 的页面atoi()还是 的页面strtol()。