gpt4 book ai didi

c - 为什么 errno 可以通过 scanf 设置为零?(当输入 "ctrl+D"时)

转载 作者:IT王子 更新时间:2023-10-29 01:22:15 27 4
gpt4 key购买 nike

手册告诉我们:errno 永远不会被任何系统调用或库函数设置为零。但是我想知道,为什么下面代码中的scanf可以将errno设置为零?(当scanf:enter the"ctrl+D")

#include <stdio.h>
#include <errno.h>
int main()
{
int i;
errno = 5;
printf("errno:%d\n",errno);
if (scanf("%d", &i) < 1)
perror("scanf");
printf("errno:%d\n",errno);
printf("i:%d\n", i);
return 0;
}

最佳答案

我可以在 glibc implementation of vfscanf() 中找到以下代码,(截至撰写本文时,链接文件中的第 589-607 行)scanf() 的实现调用:

if (skip_space || (fc != L_('[') && fc != L_('c')
&& fc != L_('C') && fc != L_('n')))
{
/* Eat whitespace. */
int save_errno = errno;
__set_errno (0);
do
/* We add the additional test for EOF here since otherwise
inchar will restore the old errno value which might be
EINTR but does not indicate an interrupt since nothing
was read at this time. */
if (__builtin_expect ((c == EOF || inchar () == EOF)
&& errno == EINTR, 0))
input_error ();
while (ISSPACE (c));
__set_errno (save_errno);
ungetc (c, s);
skip_space = 0;
}

input_error()#defined 为:

#define input_error()         do {     
errval = 1;
if (done == 0) done = EOF;
goto errout;
} while (0)

其中 errout 是最后清理代码的标签。

看起来 errnoinchar() 调用之前被设置为 0,并且旧值稍后被替换,保持 errno 不变。但是,如果发生错误并且执行了 if 语句(特别是,如果 inchar() 的计算结果为 EOF,这就是本例中发生的情况),看起来将 errno 重置为其原始值的代码可能被跳过了。话虽这么说,条件只有在 errno == EINTR 时才为真,因此不为零,在这里肯定不是这种情况,因此它可能与此代码无关,但这是我唯一可以看到 errno 被设置为 0 的地方。 inchar() 本身确实与 errno 混为一谈,正如评论所暗示的那样,并且可以将 errno 设置为 inchar_errno,它在第 223 行被初始化为 0,因此也可能存在一些其他执行路径,其中 inchar_errno 未更新但无论如何都被分配给 errno .

关于c - 为什么 errno 可以通过 scanf 设置为零?(当输入 "ctrl+D"时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19477310/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com