`errno` 的语义

Semantics of `errno`

我尝试搜索标准,但找不到任何关于 errno 的具体信息。

我的意思是有些实现将 errno 定义为全局变量,而有些将其定义为宏

#define errno (*_err_no())

标准未将其包含在标识符的保留关键字列表中。

这意味着我应该可以将 errno 用作局部变量。虽然第一个实现(将其定义为全局)应该没问题,但第二个就不行了。

是否定义了 errno 实现,或者我是否遗漏了什么?

来自最新的C11草案(N1570),7.5 Errors <errno.h>(强调我的):

The header <errno.h> defines several macros, all relating to the reporting of error conditions.

The macros are

EDOM
EILSEQ
ERANGE

which expand to integer constant expressions with type int, distinct positive values, and which are suitable for use in #if preprocessing directives; and

errno

which expands to a modifiable lvalue that has type int and thread local storage duration, the value of which is set to a positive error number by several library functions. If a macro definition is suppressed in order to access an actual object, or a program defines an identifier with the name errno, the behavior is undefined.

这非常明确地将 errno 定义为宏,并在所有范围内保留其名称。

来自标准:

The header <errno.h> defines several macros, all relating to the reporting of error conditions.

The macros are

EDOM
EILSEQ
ERANGE

which expand to integer constant expressions with type int, distinct positive values, and which are suitable for use in #if preprocessing directives; and

errno

which expands to a modifiable lvalue that has type int and thread local storage duration, the value of which is set to a positive error number by several library functions.

(重点是我的)

因此,如果实现将错误定义为 *_err_no(),则 _err_no() 应该 return 那个 int 的位置,并且 *_err_no() 访问要编辑的位置。

它由 C-Standard

明确定义

7.5 Errors

  1. The header defines several macros, all relating to the reporting of error conditions.

  2. 2 The macros are EDOM EILSEQ ERANGE which expand to integer constant expressions with type int, distinct positive values, and which are suitable for use in #if preprocessing directives; and errno which expands to a modifiable lvalue201) that has type int and thread local storage duration, the value of which is set to a positive error number by several library functions. If a macro definition is suppressed in order to access an actual object, or a program defines an identifier with the name errno, the behavior is undefined.

  3. The value of errno in the initial thread is zero at program startup (the initial value of errno in other threads is an indeterminate value), but is never set to zero by any library function.202) The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this International Standard.

  4. Additional macro definitions, beginning with E and a digit or E and an uppercase letter,203) may also be specified by the implementation.

强调我的