Я проверяю исходный код для errno.h здесь:
http://unix.superglobalmegacorp.com/Net2/newsrc/sys/errno.h.html
Это показывает, что errno объявлен как extern, и когда мы используем errno, мы можем присвоить ему значение напрямую. Это означает, что errno определен и размещен где-то еще, где определено действительно?
В связанном примере с исходным кодом с авторским правом более 20 лет назад, скорее всего, библиотека времени выполнения C имеет переменную int errno;
где-то. extern int errno;
в заголовке просто означает, что «эта переменная существует, вы найдете ее где-то еще» — возможно, рядом с кодом, который фактически вызывает ваш main
функция или что-то подобное.
Обычно в современной ОС с потоками, errno
не является строго переменной
Это пример в Linux, из /usr/include/bits/errno.h в glibc.
# ifndef __ASSEMBLER__
/* 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
# endif /* !__ASSEMBLER__ */
#endif /* _ERRNO_H */
Как это __errno_location
Реализация зависит от того, какая версия какой ОС, но, по сути, это что-то вроде:
__thread int errno;
где __thread
переводит C ++ 11 thread_local
спецификатор хранилища, и поддерживается ОС как своего рода хранилище типа «замена данных на поток». Как именно это реализовано, снова зависит от ОС. В x86 и x86-64 fs
а также gs
используются для хранения «на процессор» и «на поток» (но они «противоположны», и я не могу вспомнить, какой именно сейчас)
Других решений пока нет …