当其中一个UNIX系统函数发生错误时,通常会返回负值,并将整数
errno设置为一个值,从而提供其他信息. - UNIX环境中的高级编程,第1.7节
这看起来很奇怪:
errno需要是线程本地的.errno哪个也是另一个函数调用.为什么不在返回值中编码错误状态?
主要由于历史原因.
请注意,在现实中,errno是不是一个普通的全局变量今日(那是在上世纪80年代的情况下).这是今天(C99,C11 ...)宏-通常是扩展到一些函数调用,或许__errno()(和最近的C标准要求 errno做个宏,见n1570第7.5节); 或者它可能会扩展到一些线程局部变量,甚至一些编译器魔法.
errno 想要成为多线程需求的宏,所以我想标准的演变要求它是一些宏
所以你应该#include <errno.h>使用errno宏几乎就像它是一个全局变量,但知道它实际上不是一个.
细节是特定于实现的.查看C标准库的源代码,例如musl-libc在errno/__ errno_location.c中
int *__errno_location(void)
{
return &__pthread_self()->errno_val;
}
Run Code Online (Sandbox Code Playgroud)
并在include/errno.h公共标题中:
int *__errno_location(void);
#define errno (*__errno_location())
Run Code Online (Sandbox Code Playgroud)
和GNU libc有一些非常相似的东西
BTW一些系统函数不返回整数(例如mmap),并且一些POSIX函数不指示错误errno,例如dlopen(参见dlerror).因此,在某些标准中很难保证每个错误都可以由返回值指示.
我会为此引用Linus Torvalds。
“ errno”是UNIX中少数真正糟糕的愚蠢之一。Linux已修复它,并且不在内部使用它,也永远不会使用它。太糟糕了,用户空间已经修复了正确的错误代码返回内核做,并把它变成向后兼容的“错误号”的愚蠢。
[...]
“ errno”是不应该存在的那些根本破坏的事物之一。在原始UNIX中这是错误的,现在是错误的。
[...]
Linux返回负错误号的方法要好得多。它本质上是线程安全的,并且没有性能下降。当然,这确实取决于是否有足够的结果域,您可以始终将错误返回与良好返回分开,但是实际上对于所有系统调用都是如此。
| 归档时间: |
|
| 查看次数: |
636 次 |
| 最近记录: |