我正在阅读有关头文件errno
变量的可用材料。<errno.h>
我读 :
“值为 0 表示程序中没有错误。”和“作为一个好的做法,开发人员应该errno
在程序初始化时设置为 0”
按照惯例,我们errno
仅在发生错误时才检查变量(例如某些返回 -1 的函数)。
errno
问题1:那么启动程序前设置为0有什么用呢?
更多,我读到最好将错误号存储到局部变量然后检查它,即
if (somecall() == -1) {
printf("somecall() failed\n");
if (errno == ...) { ... }
}
在上面的代码中,如果 发生一些错误,printf()
函数调用可能会覆盖 的值。errno
printf()
问题2:上面的说法是否适用于perror()
和strerror()
,因为它们也是系统调用,并且也有可能发生错误。
errno
在 Richard Stevens 的《UNIX 环境高级编程》中,我读到,只有当函数的返回值指示发生错误时,我们才应该检查 的值。我不懂为什么 ?
答案1
按照惯例,我们
errno
仅在发生错误时才检查变量(例如某些返回 -1 的函数)。
errno
问题1:那么启动程序前设置为0有什么用呢?
事实上,我们应该只检查errno
发生错误的情况。这是因为如果没有发生错误,那么仍然可能errno
包含非零值(例如,如果在执行库调用期间发生错误但错误已恢复)。
因此,errno
在“启动程序”之前设置为 0 是没有必要的,我不会遵循这个建议。
更多,我读到最好将错误号存储到局部变量,然后检查它
是的!您关于printf()
能够破坏的观察errno
是正确的。如果需要保留其值,则应在错误发生后尽快将其复制到局部变量。
问题2:上面的说法是否适用于perror()和strerror(),因为它们也是系统调用,并且也有可能发生错误。
perror()
可能不会调用任何修改 的内容errno
,但如果确实如此,则必须小心地在errno
此之前复制 的值。我相信您可以假设它perror()
在您的系统上可以正常工作!
strerror()
不需要担心这一点,因为它以错误号作为参数,所以即使在哪里破坏errno
以前的值已经被保存了。
errno
在 Richard Stevens 的《UNIX 环境高级编程》中,我读到,只有当函数的返回值指示发生错误时,我们才应该检查 的值。我不懂为什么 ?
因为在失败时设置的系统调用和库调用errno
不需要在成功时设置它,所以它保留之前的任何值。
答案2
回答问题1,为什么我们要errno
在程序开始时设置为0是在某些时候,一些白痴可能会修改程序并使用该errno
值,而不检查先前的系统调用是否失败(errno
仅在失败时设置,在成功时不会重置为 0)。
perror()
并且strerror()
是不是系统调用,它们是库函数。他们会注意保留errno
被调用时的原始值。 (实际上strerror()
可能是一个宏 ( ),因此只有当您知道它具有有效值#define
时才应该调用它。)errno