2013-08-15 13 views
40

Questa domanda può derivare da un equivoco di compilatori da parte mia, ma qui va ...Come può un compilatore C essere scritto in C?

Si può trovare la seguente dichiarazione nella prefazione alla prima edizione del K & R (pagina xi):

il sistema operativo, il compilatore C, ed essenzialmente tutti i programmi di applicazioni UNIX (compreso tutto il software usato per preparare questo libro) sono scritti in C.

(il corsivo è mio)

Ecco cosa non capisco: non è necessario compilare il compilatore C prima che possa compilare un codice C? E se il compilatore C è scritto in C, la compilazione non richiederebbe un compilatore C già esistente ?!

L'unico modo per uscire da questo enigma di regressione infinita (o problema di pollo e uovo) è che il compilatore C scritto in C a cui si riferisce K & R è stato effettivamente compilato con un compilatore C già esistente che è stato scritto in una lingua diversa da C. Il compilatore C scritto in C ha sostituito il secondo.

O sono completamente fuori servizio?

+1

Bene, si inizia con uno in assemblaggio o qualsiasi altra cosa, e una volta che lo si possiede, è possibile usarlo per crearne uno in C e così via in seguito. – chris

risposta

28

Si chiama Bootstrapping, citando Wikipedia:

Se uno ha bisogno di un compilatore per il linguaggio X per ottenere un compilatore per il linguaggio X (che è scritto in linguaggio X), come ha fatto il primo compilatore ottenere scritto? Possibili metodi per risolvere questo pollo o il problema uovo includono:

  1. Implementazione di un interprete o compilatore per il linguaggio in linguaggio X Y. Niklaus Wirth ha riferito che ha scritto il primo compilatore Pascal in Fortran.
  2. Un altro interprete o compilatore per X è già stato scritto in un'altra lingua Y; questo è come Scheme è spesso bootstrap.
  3. Le versioni precedenti del compilatore sono state scritte in un sottoinsieme di X per che esisteva qualche altro compilatore; questo è il modo in cui alcuni superset di Java, Haskell e il compilatore Free Pascal iniziale sono bootstrap.
  4. Il compilatore per X è cross compilato da un'altra architettura dove esiste un compilatore per X; questo è il modo in cui i compilatori per C sono generalmente portati su altre piattaforme. Anche questo è il metodo utilizzato per Pascal gratuito dopo il bootstrap iniziale.
  5. Scrittura del compilatore in X; quindi compila manualmente dal sorgente (la maggior parte di probabilmente in modo non ottimizzato) ed esegui quello sul codice per ottenere un compilatore ottimizzato. Donald Knuth ha usato questo per il suo sistema di programmazione WEB literate .

E se sei interessato, here è il primo compilatore C di Dennis Richie.

8

Vedere la sezione uovo e la gallina del Wikipedia page:

Se uno ha bisogno di un compilatore per il linguaggio X per ottenere un compilatore per il linguaggio X (che è scritto in linguaggio X), come ha fatto il primo compilatore ottenere scritto? Possibili metodi per risolvere questo pollo o il problema uovo includono:

  • Implementazione di un interprete o compilatore per il linguaggio in linguaggio X Y. Niklaus Wirth ha riferito che ha scritto il primo compilatore Pascal in Fortran.
  • Un altro interprete o compilatore per X è già stato scritto in un'altra lingua Y; questo è come Scheme è spesso bootstrap.
  • Le versioni precedenti del compilatore sono state scritte in un sottoinsieme di X per il quale esisteva qualche altro compilatore; questo è il modo in cui alcuni superset di Java, Haskell e il compilatore Free Pascal iniziale sono bootstrap.
  • Il compilatore per X è cross compilato da un'altra architettura in cui esiste un compilatore per X; questo è il modo in cui i compilatori per C vengono solitamente portati su altre piattaforme. Anche questo è il metodo utilizzato per Free Pascal dopo il bootstrap iniziale.
  • Scrittura del compilatore in X; quindi compila a mano dal sorgente (molto probabilmente in modo non ottimizzato) e eseguilo sul codice per ottenere un compilatore ottimizzato. Donald Knuth ha usato questo per il suo sistema di programmazione informatizzato WEB.
+0

Pascal cuoq ... \t Nel primo punto, il linguaggio Y dovrebbe avere prima un compilatore, giusto? Penso che linguaggi come Clojure siano stati scritti in questo modo. Potresti spiegare "Compilare a mano"? – AV94

5

Di solito, un primo compilatore è scritto in un'altra lingua (direttamente in assembler PDP11 in questo caso, o in C per la maggior parte delle lingue "moderne"). Quindi, questo primo compilatore viene utilizzato per programmare un compilatore scritto nella lingua stessa.

È possibile leggere questo page sulla cronologia del linguaggio C. Vedrai che è anche fortemente collegato al sistema UNIX.

+0

Fai attenzione a trasportare le verità del 1970 ad oggi. GCC è passato a C++ :-) –

+0

Hmmm, GCC in C++ ... Sono un po 'dubbioso (e anche spaventato! :-)). – perror

+0

http://gcc.gnu.org/gcc-4.8/changes.html prima riga. –

5

È perfettamente normale che un compilatore venga scritto nella lingua che compila. Un modo per ottenere ciò sarebbe scrivere un compilatore completo per il linguaggio L in un altro linguaggio, e quindi scrivere un nuovo compilatore per L in L. Un approccio più interessante sarebbe scrivere un compilatore minimo per un sottoinsieme di L in alcuni altro linguaggio, e quindi utilizzare questo sottoinsieme minimo per migliorare il compilatore, rendendo meno minimo l'aumento del sottoinsieme di L. disponibile. In questo modo, è possibile creare un compilatore completo.

Problemi correlati