为什么glibc的fclose(NULL)会导致分段错误而不是返回错误?
根据手册页fclose(3)
:
返回值
成功完成后,将返回0。否则,
EOF
将返回并且设置全局变量errno
以指示错误。在任何一种情况下fclose()
,对该流的任何进一步访问(包括对的另一个调用)都会导致未定义的行为。错误
EBADF
底层的文件描述符fp
无效。该
fclose()
函数也可能会失败,并设置errno
为例程指定的任何错误close(2)
,write(2)
或者fflush(3)
。
当然fclose(NULL)
应该失败,但是我希望它以errno
正常方式返回,而不是直接因分段错误而死亡。是否有任何这种行为的原因?
提前致谢。
更新:我将把代码放在这里(strerror()
特别是我正在尝试)。
FILE *not_exist = NULL;not_exist = fopen("nonexist", "r");
if(not_exist == NULL){
printError(errno);
}
if(fclose(not_exist) == EOF){
printError(errno);
}
回答:
fclose
要求作为其参数一个FILE
指针通过获得任一fopen
,标准流中的一个stdin
,stdout
或stderr
,或在一些其它实现定义方式。空指针不是其中之一,因此行为是不确定的,就像是fclose((FILE
*)0xdeadbeef)这样。 在C语言中
;除了一个事实,即它保证比较不等于任何有效的指针,它只是像任何其他无效的指针,并使用它调用时的界面你将它传递给文件作为合同的一部分,除了不确定的行为NULL
具有一定的特殊的意义。
此外,返回错误将是有效的(因为无论如何该行为都是未定义的),但是对于实现来说是有害的,因为它 隐藏了未定义的行为
。调用未定义行为的最佳结果始终是崩溃,因为它会突出显示错误并允许您对其进行修复。的大多数用户fclose
不会检查错误的返回值,因此我敢打赌大多数人会愚蠢到要传递NULL
给fclose
,而他们不会足够聪明地检查的返回值fclose
。由于最终的刷新可能会失败,因此人们可能会争辩说人们通常
应该
检查的返回值fclose
,但是对于仅用于读取而打开的文件,或者如果fflush
之前被手动调用的文件,则不需要这样做。fclose
(无论如何这都是一个更聪明的习惯,因为在打开文件的同时更容易处理错误)。
以上是 为什么glibc的fclose(NULL)会导致分段错误而不是返回错误? 的全部内容, 来源链接: utcz.com/qa/403756.html