fuz*_*fuz 6 c atoi undefined-behavior language-lawyer
标准C库函数atoi在ISO 9899:2011中记录为:
7.22.1数字转换函数
1的功能
atof,atoi,atol,和atoll需要不影响整数表达式的值errno上的误差.如果无法表示结果的值,则行为未定义....
7.22.1.2的
atoi,atol和atoll功能概要
Run Code Online (Sandbox Code Playgroud)#include <stdlib.h> 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表示,分别.除了出错的行为,它们相当于Run Code Online (Sandbox Code Playgroud)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)应相当于:
Run Code Online (Sandbox Code Playgroud)(int) strtol(str, (char **)NULL, 10)除了错误的处理可能不同.如果无法表示该值,则行为未定义.
此外,应用程序使用部分说明:
atoi()函数由strtol()包含但保留,因为它在现有代码中广泛使用.如果未知该数字在范围内,则应使用strtol(),因为不需要atoi()来执行任何错误检查.
请注意,POSIX声称该规范与ISO 9899:1999一致(就我而言,它包含与ISO 9899:2011相同的语言):
此参考页面上描述的功能与ISO C标准一致.此处描述的要求与ISO C标准之间的任何冲突都是无意的.本卷POSIX.1-2008符合ISO C标准.
据我当地的POSIX委员会成员说,这是UNIX的历史行为.
行为未定义.这种解释的产生是因为§7.22.1.22从未明确说明错误发生了什么.既未定义也未明确实现已定义或未指定的行为未定义.
哪些解释是正确的?请尝试参考权威文档.
\n\n\n当字符串指向时,预期的行为是什么
\nnptr无法解析为整数时,预期的行为是什么?
需要明确的是,这个问题适用于
\n\n// Case 1\nvalue = atoi("");\nvalue = atoi(" ");\nvalue = atoi("wxyz");\nRun Code Online (Sandbox Code Playgroud)\n\n而不是以下内容:
\n\n// Case 2\n// NULL does not point to a string\nvalue = atoi(NULL);\n// Convert the initial portion, yet has following junk\nvalue = atoi("123xyz");\nvalue = atoi("123 ");\nRun Code Online (Sandbox Code Playgroud)\n\n根据整数的使用,可能/可能不是以下内容的使用情况,可能/可能不是以下内容。
\n\n// Case 3\n// Can be parsed as an _integer_, yet overflows an `int`.\nvalue = atoi("12345678901234567890123456789012345678901234567890");\nRun Code Online (Sandbox Code Playgroud)\n\n的“非情况 2”行为取决于错误ato*()的含义取决于
\n\n\n、和函数分别将指向
\natoi的字符串的初始部分转换为、和表示形式。除了error上的行为外,它们相当于\n \n \n C11dr \xc2\xa77.22.1.2 2atolatollnptrintlong intlong long intatoi: (int)strtol(nptr, (char **)NULL, 10)...
当然错误包括情况3:“如果正确值超出了可表示值的范围”。 strto*(),尽管可能不是ato*(),在这种情况下确实设置了 中定义的错误号。由于 的规范不适用于此错误,因此溢出结果为 UB 每errrno<errno.h>ato*()
\n\n\n未定义的行为在本国际标准中通过文字 \xe2\x80\x98\xe2\x80\x98undefinedbehavior\xe2\x80\x99\xe2\x80\x99 或通过省略任何明确的行为定义来表示。C11dr \xc2\xa74 2
\n
对于情况 1, 的行为strto*()已明确定义,并且未指定影响errno。规范详细介绍了 (\xc2\xa77.22.1.4 4) 并称这些为“无转换”,而不是错误。因此它可以断言情况 1 的strto*()行为不是错误,而是“无转换”。因此每...
\n\n\n“如果无法执行转换,则返回零。C11dr \xc2\xa77.22.1.4 8
\n
...atoi("")必须返回 0。
| 归档时间: |
|
| 查看次数: |
1265 次 |
| 最近记录: |