2015-11-29 3 views
0

проверить исходный код для errno.h здесь: http://unix.superglobalmegacorp.com/Net2/newsrc/sys/errno.h.htmlГде errno определено и выделено в C/C++?

Это показывает, что ERRNO объявлен как экстерн, и когда мы используем ERRNO мы можем присвоить значение к нему напрямую. Это означает, что errno определяется и распределяется где-то в другом месте, где действительно определено?

+0

'errno' must только ведут себя как глобальный 'int'. На самом деле он не должен определяться как таковой, обычно это макрос, который возвращает значение lvalue, например '#define errno (* (int *) getErrnoPtr()) или что-то в этом роде. Почему вас интересует конкретное определение? – mtijanic

+0

Тот же ответ, что и 'printf' объявлен (неявно как extern), и мы можем назвать его, поэтому где он определен? – immibis

+0

Вероятно, он выделяется, как и на самом деле, в заголовке стека потоков. Это «местоположение» - это определение ОС/архитектуры и, поскольку оно должно быть зависимым от потока, заголовок стека будет казаться очевидным местом для ОС. –

ответ

5

В связанном примере с исходным кодом с авторскими правами более 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 транслирует 11 thread_local C++ хранения спецификатор, и поддерживаемая ОС как своего рода «своп данных на поток». Именно то, как это реализовано, снова зависит от ОС. В x86 и x86-64 fs и gs используются для хранения «на процессор» и «на поток» (но они «против», и я не могу вспомнить, что именно сейчас)

Смежные вопросы