关于错误的atoi()的行为,我可以假设什么?
标准C库函数atoi
在ISO 9899:2011中记录为:
7.22.1数字转换函数
1
atof
,atoi
,atol
和atoll
函数不需要影响错误的整数表达式errno
的值。 如果无法表示结果的值,则行为未定义。…
7.22.1.2
atoi
,atol
和atoll
function概要
#include int atoi(const char *nptr); long int atol(const char *nptr); long long int atoll(const char *nptr);
描述
2
atoi
,atol
和atoll
函数分别将nptr
的字符串的初始部分转换为int
,long int
和long long int
表示。 除了出错的行为,它们相当于atoi: (int)strtol(nptr, (char **)NULL, 10) atol: strtol(nptr, (char **)NULL, 10) atoll: strtoll(nptr, (char **)NULL, 10)
返回
3
atoi
,atol
和atoll
函数返回转换后的值。
当nptr
无法解析为整数时,预期的行为是什么? 似乎存在以下四种观点:
- 不执行转换,返回零。 这是一些像这样的参考文献给出的文档。
- 行为类似于
strtol
除了可能没有设置errno
。 这是从“除错误行为除外”中引出的,作为对第7.22.1节的参考。 -
行为未指定。 这就是POSIX所说的 :
呼叫atoi(str)应相当于:
(int) strtol(str, (char **)NULL, 10)
除了错误的处理可能不同。 如果无法表示该值,则行为未定义。
此外,“ 应用程序使用 ”部分说明:
atoi()函数由strtol()包含但保留,因为它在现有代码中广泛使用。 如果未知该数字在范围内,则应使用strtol(),因为不需要atoi()来执行任何错误检查。
请注意,POSIX声称该规范与ISO 9899:1999一致(就我而言,它包含与ISO 9899:2011相同的语言):
此参考页面上描述的function与ISO C标准一致。 此处描述的要求与ISO C标准之间的任何冲突都是无意的。 此量的POSIX.1-2008符合ISO C标准。
据我当地的POSIX委员会成员说,这是UNIX的历史行为。
-
行为未定义。 这种解释的产生是因为§7.22.1.2¶2从未明确说明错误发生了什么。 既未定义也未明确实现定义或未指定的行为未定义。
哪些解释是正确的? 请尝试参考权威文档。
当
nptr
无法解析为整数时,预期的行为是什么?
需要说明的是,这个问题适用于
// Case 1 value = atoi(""); value = atoi(" "); value = atoi("wxyz");
而不是以下内容:
// Case 2 // NULL does not point to a string value = atoi(NULL); // Convert the initial portion, yet has following junk value = atoi("123xyz"); value = atoi("123 ");
根据整数的用法,可能/可能不是以下。
// Case 3 // Can be parsed as an _integer_, yet overflows an `int`. value = atoi("12345678901234567890123456789012345678901234567890");
ato*()
的“非案例2”行为取决于错误的含义
atoi
,atol
和atoll
函数分别将nptr
的字符串的初始部分转换为int
,long int
和long long int
表示。 除了出错的行为,它们相当于
atoi: (int)strtol(nptr, (char **)NULL, 10)
...
C11dr§7.22.1.22
当然错误包括案例3:“如果正确的值超出可表示值的范围”。 strto*()
,虽然可能不是ato*()
,但在这种情况下确实设置了
定义的错误号errrno
。 由于ato*()
的规范不适用于此错误 ,因此溢出(结果)为UB per
未定义的行为在本国际标准中以“未定义的行为”或“省略行为的任何明确定义”一词另有说明。 C11dr§42
对于情况1, strto*()
的行为定义良好,未指定影响errno
。 规范详细说明(§7.22.1.44)并称之为“无转换”,而不是错误 。 因此它可以断言案例1 strto*()
行为不是错误 ,而是“无转换”。 因此…
“如果不能进行转换,则返回零.C11dr§7.22.1.48
… atoi("")
必须返回0。