在系统编程中错误通常通过函数返回值来表示,并通过特殊变量errno来描述。
errno这个全局变量在<errno.h>头文件中声明如下:extern int errno
;
errno是一个由POSIX和ISO C标准定义的符号,看(用)起来就好像是一个整形变量。当系统调用或库函数发生错误的时候,比如以只读方式打开一个不存在的文件时,它的值将会被改变,根据errno值的不同,我们就可以知道自己的程序发生了什么错误,然后进行相应的处理。
为什么,要强调errno看起来好像是一个整形变量呢?因为有的标准(如ISO C) 只规定了errno的作用,而没有规定它的实现方式,它可能被定义成一个变量,也有可能被定义成一个宏,这个具体要看编译器自己的实现。早些时候,POSIX.1曾把 errno
定义成 extern int errno
这种形式,但现在这种方式比较少见了。因为以这种形式来实现 errno
,在多线程环境下errno
变量是被多个线程共享的,这样可能线程A发生某些错误改变了errno
的值,线程B虽然没有发生任何错误,但是当它检测errno的值的时候,线程B会以为自己发生了错误。所以现在errno
在Linux中被实现成extern int * __errno_location(void): #define errno (*__errno_location())
,这样每个线程都有自己的errno
,不会再发生混乱了。
关于errno
有三点需要特别注意: