我读到,当系统调用失败时,内核返回相应的错误号来说明失败。为什么此错误未直接返回给用户应用程序?
为什么glibc将此存储在全局errno
变量中?这样做的好处是什么?
将评论转移到答案中。
errno
的使用是争论的主题,但归结为“历史原因”。 Unix的早期版本可以做到这一点-后来的版本(以及标准C和POSIX)都保留了它以避免破坏正常工作的代码。 errno
机制有很多缺陷,尤其是在现代的多线程代码中。 POSIX pthread库不使用errno
。函数直接报告错误号。您可以在诸如P J Plauger errno
(1992)之类的书中找到有关The Standard C Library的异议词。它已经很老了并且描述了C90,但是今天很多仍然有用。
Error Numbers上的POSIX基本原理具有关于该主题的很多信息。特别注意“关于每线程errno
的替代解决方案”小节。
[请注意,旧的C代码可能会在源文件中写入extern int errno;
。由于多线程变得司空见惯,所以这是不正确的。在现代代码中获取errno
声明的唯一正确方法是#include <errno.h>
。这是因为名称可能是“可修改的左值”的宏。在一个系统上(macOS Catalina 10.15.2),您可以找到:
extern int * __error(void); // Do not copy this
#define errno (*__error()) // Do not copy this
与extern int errno;
完全不同。请注意,其他系统有不同的声明方式-您无法将我显示的内容复制到代码中并期望它能正常工作。包括标题;它既简单又可靠(并且是可靠地完成工作的唯一方法)。