Dans les Jours Anciens (pré-ANSI), la prédéfinition des symboles tels que unix
et vax
était une manière de permettre au code de détecter au moment de la compilation de ce système, il a été compilé. Il n'y a pas de langue officielle standard à l'époque (au-delà de la référence matériau à l'arrière de la première édition de K&R), et C le code de toute la complexité est généralement un labyrinthe complexe de #ifdef
s pour permettre des différences entre les systèmes. Ces définitions de macros ont été généralement fixé par le compilateur lui-même, ne sont pas définis dans un fichier d'en-tête de la bibliothèque. Puisqu'il n'y a pas de véritables règles sur lesquelles les identificateurs peuvent être utilisées par la mise en œuvre et qui ont été réservés pour les programmeurs, rédacteurs du compilateur s'est senti libre d'utiliser les noms simples comme unix
et à supposer que les programmeurs simplement d'éviter d'utiliser ces noms pour leurs propres fins.
1989 C ANSI standard introduit des règles de limitation des symboles à une mise en œuvre pourrait légalement prédéfinir. Une macro prédéfinie par le compilateur ne pourrait qu'avoir un nom commençant par deux caractères de soulignement, ou avec un trait de soulignement suivie par une lettre majuscule, laissant les programmeurs libres d'utiliser les identificateurs ne correspond pas à ce modèle et ne sont pas utilisés dans la bibliothèque standard.
En conséquence, un compilateur qui prédéfinit unix
ou linux
est non-conforme, car il ne pourra pas compiler parfaitement légal de code qui utilise quelque chose comme int linux = 5;
.
Il se trouve que la gcc est non-conforme par défaut -- mais elle peut être faite de se conformer (assez bien) avec les bonnes options de ligne de commande:
gcc -std=c90 -pedantic ... # or -std=c89 or -ansi
gcc -std=c99 -pedantic
gcc -std=c11 -pedantic
Voir le manuel de gcc pour plus de détails.
gcc sera l'élimination progressive de ces définitions dans les futures versions, de sorte que vous ne devriez pas écrire du code qui en dépend. Si votre programme a besoin de savoir si il est compilé pour une cible Linux ou non, il peut vérifier si __linux__
est défini (en supposant que vous êtes en utilisant gcc ou un compilateur compatible avec). Voir le préprocesseur GNU C manuel pour plus d'informations.
Une grande partie de leur pertinence à part: le "Meilleur Liner" gagnant de l'1987 International Obfuscated C Code Contest, par David Korn (oui, l'auteur de la Korn Shell) a profité de la prédéfinis unix
macro:
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Il imprime "unix"
, mais pour des raisons qui n'ont absolument rien à voir avec l'orthographe du nom de la macro.