3 回答
TA贡献1836条经验 获得超13个赞
是
Errno不再是一个简单的变量,它是幕后复杂的事情,特别是它具有线程安全性。
见$ man 3 errno:
ERRNO(3) Linux Programmer’s Manual ERRNO(3)
NAME
errno - number of last error
SYNOPSIS
#include <errno.h>
DESCRIPTION
...
errno is defined by the ISO C standard to be a modifiable lvalue of
type int, and must not be explicitly declared; errno may be a macro.
errno is thread-local; setting it in one thread does not affect its
value in any other thread.
我们可以仔细检查:
$ cat > test.c
#include <errno.h>
f() { g(errno); }
$ cc -E test.c | grep ^f
f() { g((*__errno_location ())); }
$
TA贡献1856条经验 获得超17个赞
在errno.h中,此变量声明为extern int errno;
这是C标准所说的:
宏errno不必是对象的标识符。它可能会扩展为由函数调用(例如*errno())产生的可修改的左值。
通常,errno是一个宏,它调用一个函数,该函数返回当前线程的错误号的地址,然后将其取消引用。
这是我在Linux上的/usr/include/bits/errno.h:
/* Function to get address of global `errno' variable. */
extern int *__errno_location (void) __THROW __attribute__ ((__const__));
# if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value. */
# define errno (*__errno_location ())
# endif
最后,它将生成这种代码:
> cat essai.c
#include <errno.h>
int
main(void)
{
errno = 0;
return 0;
}
> gcc -c -Wall -Wextra -pedantic essai.c
> objdump -d -M intel essai.o
essai.o: file format elf32-i386
Disassembly of section .text:
00000000 <main>:
0: 55 push ebp
1: 89 e5 mov ebp,esp
3: 83 e4 f0 and esp,0xfffffff0
6: e8 fc ff ff ff call 7 <main+0x7> ; get address of errno in EAX
b: c7 00 00 00 00 00 mov DWORD PTR [eax],0x0 ; store 0 in errno
11: b8 00 00 00 00 mov eax,0x0
16: 89 ec mov esp,ebp
18: 5d pop ebp
19: c3 ret
- 3 回答
- 0 关注
- 831 浏览
添加回答
举报