为什么在程序初始化时将errno设置为零并且在错误发生之前无法测试它?

为什么在程序初始化时将errno设置为零并且在错误发生之前无法测试它?

我正在阅读有关头文件errno变量的可用材料。<errno.h>

我读 :

“值为 0 表示程序中没有错误。”和“作为一个好的做法,开发人员应该errno在程序初始化时设置为 0”

按照惯例,我们errno仅在发生错误时才检查变量(例如某些返回 -1 的函数)。

errno问题1:那么启动程序前设置为0有什么用呢?

更多,我读到最好将错误号存储到局部变量然后检查它,即

 if (somecall() == -1) {
      printf("somecall() failed\n");
      if (errno == ...) { ... }
      }

在上面的代码中,如果 发生一些错误,printf()函数调用可能会覆盖 的值。errnoprintf()

问题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

相关内容