我可以假设 atoi() 出错时的行为是什么?
What can I assume about the behaviour of atoi() on error?
标准 C 库函数 atoi
在 ISO 9899:2011 中记录为:
7.22.1 Numeric conversion functions
1 The functions atof
, atoi
, atol
, and atoll
need not affect the value of the integer expression errno
on an error. If the value of the result cannot be represented, the behavior is undefined.
...
7.22.1.2 The atoi
, atol
, and atoll
functions
Synopsis
#include <stdlib.h>
int atoi(const char *nptr);
long int atol(const char *nptr);
long long int atoll(const char *nptr);
Description
2 The atoi
, atol
, and atoll
functions convert the initial portion of the string pointed to by nptr
to int
, long int
, and long long int
representation, respectively. Except for the behavior on error, they are equivalent to
atoi: (int)strtol(nptr, (char **)NULL, 10)
atol: strtol(nptr, (char **)NULL, 10)
atoll: strtoll(nptr, (char **)NULL, 10)
Returns
3 The atoi
, atol
, and atoll
functions return the converted value.
当 nptr
指向的字符串无法解析为整数时,预期的行为是什么?似乎存在以下四种意见:
不执行转换并返回零。这是一些参考文献给出的文档,如 this one.
行为与 strtol
的行为类似,只是可能未设置 errno
。这源于将“错误行为除外”作为对 §7.22.1 ¶1 的引用。
行为未指定。这就是 POSIX says:
The call atoi(str) shall be equivalent to:
(int) strtol(str, (char **)NULL, 10)
except that the handling of errors may differ. If the value cannot be represented, the behavior is undefined.
此外,应用程序使用部分指出:
The atoi() function is subsumed by strtol() but is retained because it is used extensively in existing code. If the number is not known to be in range, strtol() should be used because atoi() is not required to perform any error checking.
请注意,POSIX 声称该规范与 ISO 9899:1999 一致(据我所知,它包含与 ISO 9899:2011 相同的语言):
The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2008 defers to the ISO C standard.
据我当地的 POSIX 委员会成员说,这是 UNIX 的历史行为。
行为未定义。出现这种解释是因为 §7.22.1.2 ¶2 从未明确说明错误时会发生什么。既未定义也未明确实现定义或未指定的行为是未定义的。
以下哪种解释是正确的?请尽量参考权威文档
What is the intended behaviour when string pointed to by nptr
cannot be parsed as an integer?
明确地说,这个问题适用于
// 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 ");
和 maybe/maybe 不是以下取决于 integer.
的用法
// Case 3
// Can be parsed as an _integer_, yet overflows an `int`.
value = atoi("12345678901234567890123456789012345678901234567890");
ato*()
的 "non-Case 2" 行为取决于
中 error 的含义
The atoi
, atol
, and atoll
functions convert the initial portion of the string pointed to by nptr
to int
, long int
, and long long int
representation, respectively. Except for the behavior on error, they are equivalent to
atoi: (int)strtol(nptr, (char **)NULL, 10)
...
C11dr §7.22.1.2 2
当然 错误 包括情况 3:"If the correct value is outside the range of representable values"。 strto*()
,虽然可能不是 ato*()
,但在这种情况下确实设置了 <errno.h>
中定义的 错误 数字 errrno
。由于 ato*()
的规范不适用于此 错误 ,溢出,结果是 UB per
Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. C11dr §4 2
对于情况 1,strto*()
的行为定义明确,未指定影响 errno
。规范详细介绍了 (§7.22.1.4 4) 并将这些称为 "no conversion",而不是 error。因此它可以断言案例 1 strto*()
行为不是 错误 ,而是 "no conversion"。因此每 ...
"If no conversion could be performed, zero is returned. C11dr §7.22.1.4 8
...atoi("")
必须 return 0.
标准 C 库函数 atoi
在 ISO 9899:2011 中记录为:
7.22.1 Numeric conversion functions
1 The functions
atof
,atoi
,atol
, andatoll
need not affect the value of the integer expressionerrno
on an error. If the value of the result cannot be represented, the behavior is undefined....
7.22.1.2 The
atoi
,atol
, andatoll
functionsSynopsis
#include <stdlib.h> int atoi(const char *nptr); long int atol(const char *nptr); long long int atoll(const char *nptr);
Description
2 The
atoi
,atol
, andatoll
functions convert the initial portion of the string pointed to bynptr
toint
,long int
, andlong long int
representation, respectively. Except for the behavior on error, they are equivalent toatoi: (int)strtol(nptr, (char **)NULL, 10) atol: strtol(nptr, (char **)NULL, 10) atoll: strtoll(nptr, (char **)NULL, 10)
Returns
3 The
atoi
,atol
, andatoll
functions return the converted value.
当 nptr
指向的字符串无法解析为整数时,预期的行为是什么?似乎存在以下四种意见:
不执行转换并返回零。这是一些参考文献给出的文档,如 this one.
行为与
strtol
的行为类似,只是可能未设置errno
。这源于将“错误行为除外”作为对 §7.22.1 ¶1 的引用。行为未指定。这就是 POSIX says:
The call atoi(str) shall be equivalent to:
(int) strtol(str, (char **)NULL, 10)
except that the handling of errors may differ. If the value cannot be represented, the behavior is undefined.
此外,应用程序使用部分指出:
The atoi() function is subsumed by strtol() but is retained because it is used extensively in existing code. If the number is not known to be in range, strtol() should be used because atoi() is not required to perform any error checking.
请注意,POSIX 声称该规范与 ISO 9899:1999 一致(据我所知,它包含与 ISO 9899:2011 相同的语言):
The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2008 defers to the ISO C standard.
据我当地的 POSIX 委员会成员说,这是 UNIX 的历史行为。
行为未定义。出现这种解释是因为 §7.22.1.2 ¶2 从未明确说明错误时会发生什么。既未定义也未明确实现定义或未指定的行为是未定义的。
以下哪种解释是正确的?请尽量参考权威文档
What is the intended behaviour when string pointed to by
nptr
cannot be parsed as an integer?
明确地说,这个问题适用于
// 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 ");
和 maybe/maybe 不是以下取决于 integer.
的用法// Case 3
// Can be parsed as an _integer_, yet overflows an `int`.
value = atoi("12345678901234567890123456789012345678901234567890");
ato*()
的 "non-Case 2" 行为取决于
The
atoi
,atol
, andatoll
functions convert the initial portion of the string pointed to bynptr
toint
,long int
, andlong long int
representation, respectively. Except for the behavior on error, they are equivalent to
atoi: (int)strtol(nptr, (char **)NULL, 10)
...
C11dr §7.22.1.2 2
当然 错误 包括情况 3:"If the correct value is outside the range of representable values"。 strto*()
,虽然可能不是 ato*()
,但在这种情况下确实设置了 <errno.h>
中定义的 错误 数字 errrno
。由于 ato*()
的规范不适用于此 错误 ,溢出,结果是 UB per
Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. C11dr §4 2
对于情况 1,strto*()
的行为定义明确,未指定影响 errno
。规范详细介绍了 (§7.22.1.4 4) 并将这些称为 "no conversion",而不是 error。因此它可以断言案例 1 strto*()
行为不是 错误 ,而是 "no conversion"。因此每 ...
"If no conversion could be performed, zero is returned. C11dr §7.22.1.4 8
...atoi("")
必须 return 0.