当前位置: C语言 -- 标准库 -- <errno.h> -- errno

errno宏


概要:

#define errno value //value值由具体实现定义。


描述:

该宏记录最近一次错误编号。该宏会扩展为具有线程存储期限的int类型的可修改左值,其值由库函数设置为正错误数(宏errno不必是对象标识符。它可能会扩展为函数调用产生的可修改左值,例如:*errno()。)。如果为了访问实际对象而禁止宏errno定义,或者程序定义了名为errno的标识符,其行为是未定义的。

程序开始时,初始线程中的errno值为0(其它线程中errno的初始值是不确定的。);但永远不会被任何库函数设置为0。因此,使用宏errno进行错误检查的程序在库函数调用前将其设置为0,然后在后续库函数调用前对其进行检查。当然库函数可以在开始时先保存宏errno的值,然后再将宏errno设置为0,只要在库函数返回前,宏errno仍然为0,原先值就可以恢复。

如果在库函数的说明文档中未记录宏errno的使用,无论是否存在错误,库函数调用都可能将宏errno设置为非0值。


GCC编译器中宏errno定义如下所示:

#define errno (*_errno())

Visual Studio编译器中宏errno定义如下所示:

#define errno (*_errno())

Pelles C编译器中宏errno定义如下所示:

#define errno (*__errno())


范例:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
/*宏errno范例*/

#include <errno.h>
#include <math.h>
#include <stdio.h>

void showError(void)
{
    /*判断是否出错。*/
    if(errno != 0)
    {
        /*判断错误类型。*/
        switch(errno)
        {
            case EDOM:puts("Error: out of domain");
                      break;
            case ERANGE:puts("Error: out of range");
                        break;
            case EILSEQ:puts("Error: illegal byte sequence");
                        break;
            default:puts("Other errors");
                    break;
        }
    }
}

int main(void)
{
    double a;
    double b;

    errno = 0;
    a = sqrt(-1.0);
    showError();

    errno = 0;
    b = pow(1000.0,1000.0);
    showError();

    return 0;
}


输出:

Error: out of domain

Error: out of range

在这个例子中,sqrt函数要求参数为非负数,-1.0不在域中;pow(1000.0,1000.0)函数的返回值已超出double类型所能表示的范围。


相关内容:
EDOM 域错误。
EILSEQ 非法字节序列。
ERANGE 范围错误。