web-dev-qa-db-fra.com

Comment un compilateur C peut-il être écrit en C?

Cette question peut provenir d'une mauvaise compréhension des compilateurs de ma part, mais voici ...

On peut trouver l'énoncé suivant dans la préface de la première édition de K&R (page xi):

Le système d'exploitation, le compilateur C, et essentiellement tous les programmes d'application UNIX (y compris tous les logiciels utilisés pour préparer ce livre) sont écrits en C.

(mon accent)

Voici ce que je ne comprends pas: ce compilateur C ne doit-il pas être compilé lui-même avant de pouvoir compiler du code C? Et si ce compilateur C est écrit en C, sa compilation ne nécessiterait-elle pas un compilateur C déjà existant?!

Le seul moyen de sortir de cette énigme de régression infinie (ou problème de poulet et d'oeufs) est que le compilateur C écrit en C auquel K&R fait référence a été effectivement compilé avec un compilateur C déjà existant qui a été écrit dans un langage autre que C Le compilateur C écrit en C a alors remplacé ce dernier.

Ou suis-je complètement éteint?

55
jub0bs

Cela s'appelle Bootstrapping , citant Wikipedia:

Si l'on a besoin d'un compilateur pour la langue X pour obtenir un compilateur pour la langue X (qui est écrit en langage X), comment le premier compilateur a-t-il été écrit? Les méthodes possibles pour résoudre ce poulet ou le problème des œufs comprennent:

  1. Implémenter un interpréteur ou un compilateur pour la langue X dans la langue Y. Niklaus Wirth a indiqué qu'il a écrit le premier compilateur Pascal dans Fortran.
  2. Un autre interpréteur ou compilateur pour X a déjà été écrit dans une autre langue Y; c'est ainsi que Scheme est souvent amorcé.
  3. Les versions antérieures du compilateur étaient écrites dans un sous-ensemble de X pour lequel il existait un autre compilateur; C'est ainsi que certains sur-ensembles de Java, Haskell et du compilateur Free Pascal initial sont amorcés.
  4. Le compilateur pour X est compilé de manière croisée à partir d'une autre architecture où il existe un compilateur pour X; c'est ainsi que les compilateurs pour C sont généralement portés sur d'autres plateformes. C'est également la méthode utilisée pour Free Pascal après le bootstrap initial.
  5. Écriture du compilateur en X; puis le compiler à la main à partir de la source (très probablement de manière non optimisée) et l'exécuter sur le code pour obtenir un compilateur optimisé. Donald Knuth l'a utilisé pour son système de programmation WEB.

Et si vous êtes intéressé, ici est la première source du compilateur C de Dennis Richie.

39
Yu Hao

Voir la section Poulet et oeufs de la page Wikipedia :

Si l'on a besoin d'un compilateur pour la langue X pour obtenir un compilateur pour la langue X (qui est écrit en langage X), comment le premier compilateur a-t-il été écrit? Les méthodes possibles pour résoudre ce poulet ou le problème des œufs comprennent:

  • Implémenter un interpréteur ou un compilateur pour la langue X dans la langue Y. Niklaus Wirth a indiqué qu'il a écrit le premier compilateur Pascal dans Fortran.
  • Un autre interpréteur ou compilateur pour X a déjà été écrit dans une autre langue Y; c'est ainsi que Scheme est souvent amorcé.
  • Les versions antérieures du compilateur étaient écrites dans un sous-ensemble de X pour lequel il existait un autre compilateur; C'est ainsi que certains sur-ensembles de Java, Haskell et du compilateur Free Pascal initial sont amorcés.
  • Le compilateur pour X est compilé de manière croisée à partir d'une autre architecture où il existe un compilateur pour X; c'est ainsi que les compilateurs pour C sont généralement portés sur d'autres plateformes. C'est également la méthode utilisée pour Free Pascal après le bootstrap initial.
  • Écriture du compilateur en X; puis le compiler à la main à partir de la source (très probablement de manière non optimisée) et l'exécuter sur le code pour obtenir un compilateur optimisé. Donald Knuth l'a utilisé pour son système de programmation WEB.
9
Pascal Cuoq

Habituellement, un premier compilateur est écrit dans un autre langage (directement dans l'assembleur PDP11 dans ce cas, ou en C pour la plupart des langages "modernes"). Ensuite, ce premier compilateur est utilisé pour programmer un compilateur écrit dans le langage lui-même.

Vous pouvez lire ceci page sur l'histoire du langage C. Vous verrez qu'il est également fortement lié au système UNIX.

6
perror

Il est parfaitement normal qu'un compilateur soit écrit dans le langage qu'il compile. Une façon d'y parvenir serait d'écrire un compilateur complet pour le langage L dans un autre langage, puis d'écrire un nouveau compilateur pour L en L. Une approche plus intéressante serait d'écrire un compilateur minimal pour un sous-ensemble de L dans certains autre langage, puis utilisez ce sous-ensemble minimal pour améliorer le compilateur, le rendant moins minimal en augmentant le sous-ensemble disponible de L. De cette façon, un compilateur complet peut être construit.

5
Jon Kiparsky