Dans l'exemple lié au code source avec un copyright datant de plus de 20 ans, la bibliothèque d'exécution C a probablement une variable int errno;
quelque part. extern int errno;
dans un en-tête signifie simplement "cette variable existe, vous la trouverez ailleurs" - peut-être à côté du code qui appelle réellement votre main
, ou quelque chose de similaire.
Typiquement dans un système d'exploitation moderne avec des threads, errno
n'est pas strictement une variable.
Ceci est l'exemple sous Linux, à partir de /usr/include/bits/errno.h dans la 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 */
Exactement comment cela le __errno_location
est mis en œuvre dépend de la version de ce système d'exploitation, mais essentiellement, il y a quelque chose comme:
__thread int errno;
où __thread
se traduit par le spécificateur de stockage C++ 11 thread_local
, et est pris en charge par le système d'exploitation comme une sorte de stockage de type «échange de données par thread». Exactement comment cela est mis en œuvre est encore en fonction de l'OS. En x86 et x86-64, fs
et gs
sont utilisés pour "par CPU" et "par thread" de stockage (mais ils sont "opposés" et je ne me souviens pas très bien lequel est en ce moment)
'errno' doit seulement se comporter comme un «int» global. Il n'a pas besoin d'être défini en tant que tel, en général c'est une macro qui retourne une lvalue, comme '#define errno (* (int *) getErrnoPtr())' ou quelque chose. Pourquoi vous souciez-vous de la définition spécifique? – mtijanic
La même réponse que: 'printf' est déclaré (implicitement comme extern), et nous pouvons l'appeler, alors où est-il défini? – immibis
Il est probablement affecté, comme dans le stockage réel, dans l'en-tête de la pile de threads. Son 'emplacement' est OS/architecture défini et, puisqu'il doit être spécifique au thread, l'en-tête de la pile semble être l'endroit évident pour le système d'exploitation pour le mettre. –