Wie könnte der erste C ++ - Compiler in C ++ geschrieben werden?


48

Stroustrup behauptet, dass Cfront, der erste C ++ - Compiler, in C ++ geschrieben wurde ( Stroustrup FAQ ).

Wie ist es jedoch überhaupt möglich, dass der erste C ++ - Compiler in C ++ geschrieben wird?

Der Code, aus dem der Compiler besteht, muss ebenfalls kompiliert werden, sodass der erste C ++ - Compiler nicht in C ++ geschrieben werden konnte, oder?


6
en.wikipedia.org/wiki/Cfront behandelt das Problem leicht.
Christofr

Antworten:


57

Der Schlüssel ist hier richtig:

Der erste C ++ - Compiler (Cfront) wurde in C ++ geschrieben. Um das zu erstellen, habe ich zuerst C verwendet, um einen "C with Classes" -to-C-Präprozessor zu schreiben. "C mit Klassen" war ein C-Dialekt, der der unmittelbare Vorfahr von C ++ wurde. Dieser Präprozessor hat "C with Classes" -Konstrukte (wie Klassen und Konstruktoren) in C übersetzt. Es war ein traditioneller Präprozessor, der nicht die gesamte Sprache verstand, den Großteil der Typprüfung dem C-Compiler überließ und einzelne übersetzte Konstrukte ohne vollständige Kenntnisse. Ich habe dann die erste Version von Cfront in "C with Classes" geschrieben.

Die erste Version von Cfront wurde also nicht in C ++, sondern in der Zwischensprache geschrieben. Die Möglichkeit, C-Compiler und Präprozessoren direkt in C zu erstellen, führte zu vielen Neuerungen (und massiven Sicherheitslücken ) in C. Sie schreiben also Ihren neuen Präprozessor, der Ihren Code "C mit Klassen" in direktes C umwandelt (weil direktes C dies kann) irgendetwas) und dann schreiben Sie mit "C with Classes" einen C ++ - Compiler (nicht, dass dies in C nicht möglich wäre, es würde nur eine Weile dauern) und dann schreiben Sie mit diesem C ++ - Compiler einen effizienteren / vollständigeren Compiler C ++. Verstanden?


5
+1 für das Einbinden eines Links zu einer meiner Lieblingsgeschichten von Dingen, die getan werden können (und sollten).
jwernerny

3
Der Compiler wurde in gültigem C ++ - Code geschrieben, verwendete jedoch nur einige der vollständigen C ++ - Funktionen, die vom Präprozessor "C with Classes" unterstützt wurden. Es wurde eine Teilmenge der vollständigen Sprache verwendet, sodass es auch für das Ergebnis kompiliert wurde (die erste funktionierende Version von Cfront). Nach diesem "Bootstrap" -Schritt musste er den Präprozessor wahrscheinlich nie wieder verwenden.
Joeytwiddle

2
@jwernerny - Ich habe diesen Artikel immer als unbefriedigend empfunden. Er beschönigt den schwierigsten und nicht trivialen Teil: "Der Fehler würde mit dem Code im UNIX-Anmeldebefehl übereinstimmen. Der Ersatzcode würde den Anmeldebefehl falsch kompilieren, sodass er entweder das beabsichtigte verschlüsselte Kennwort oder ein bestimmtes bekanntes Kennwort akzeptiert. " Aber wie würde das gemacht werden? Wurde es jemals tatsächlich demonstriert?
Detly

3
"führte zu vielen Neuerungen (und massiven Sicherheitslücken) in C": Soweit ich weiß, können diese Tricks in jeder Sprache angewendet werden, nicht nur in C. So kann jede andere Sprache die gleichen Sicherheitslücken aufweisen.
Giorgio

2
@detly: Es klingt jetzt trivial, aber 1983 war dies ein neuartiger Angriff, der durch mangelnde Implementierungsvielfalt möglich wurde. Damals vertrauten wir mehr auf Binärdateien, zum Teil, weil das Kompilieren von allem aus dem Quellcode eine viel größere Tortur war als heute.
Blrfl

17

Es wurde bootstrapped. Sobald eine C ++ - Funktion zu cfront hinzugefügt wurde, kann cfront diese Funktion auch ab diesem Zeitpunkt verwenden (jedoch nicht, um genau diese Funktion zu implementieren). Dies funktionierte, weil cfront C ++ - Code in C-Code konvertieren konnte. Wenn also eine neue Plattform herauskommt, können Sie cfront auf einer anderen Plattform verwenden, um cfront von C ++ nach C zu konvertieren, und dann den C-Compiler der neuen Plattform verwenden, um die Kompilierung von C nach Objektcode abzuschließen.


9

Ich denke, BS beantwortet diese Frage:

Der erste C ++ - Compiler (Cfront) wurde in C ++ geschrieben. Um das zu erstellen, habe ich zuerst C verwendet, um einen "C with Classes" -to-C-Präprozessor zu schreiben. "C mit Klassen" war ein C-Dialekt, der der unmittelbare Vorfahr von C ++ wurde. Dieser Präprozessor hat "C with Classes" -Konstrukte (wie Klassen und Konstruktoren) in C übersetzt. Es war ein traditioneller Präprozessor, der nicht die gesamte Sprache verstand, den Großteil der Typprüfung dem C-Compiler überließ und einzelne übersetzte Konstrukte ohne vollständige Kenntnisse.

Ich habe dann die erste Version von Cfront in "C with Classes" geschrieben. Cfront war ein traditioneller Compiler, der die vollständige Syntax- und Semantikprüfung der C ++ - Quelle durchführte. Zu diesem Zweck verfügte es über einen vollständigen Parser, erstellte Symboltabellen und erstellte eine vollständige interne Baumdarstellung für jede Klasse, Funktion usw. Vor der Ausgabe von C optimierte es auch die interne Baumdarstellung von C ++ - Konstrukten generiertes C, hat sich bei keiner Typprüfung auf C verlassen. Es wurde einfach C als Assembler verwendet. Der resultierende Code war kompromisslos schnell.

Zuerst erstellte er etwas, das er "C mit Klassen" nannte und das von einem einfachen Präprozessor in C implementiert wurde. Es war im Grunde C ++, aber der Präprozessor überprüfte nur wenig oder gar nicht. Er benutzte das dann, um Cfront zu schreiben, die mächtigere Version des Übersetzers von C ++ in C, komplett mit Typprüfung, Symboltabellen usw.


1
Wenn wir also ein C ++ - Programm kompilieren, wird es in C konvertiert. Nachdem es in C konvertiert wurde, wird es erneut in Maschinencode kompiliert.
Pacerier

@ Pacerier: Ursprünglich ja, aber jetzt denke ich nicht.
Mike Dunlavey

Ich verstehe deinen Kommentar nicht ganz. Meinen Sie jetzt, dass es Compiler gibt, die den zweiten Schritt überspringen und einfach die C ++ - Quelle nehmen und zu Maschinencode kompilieren?
Pacerier

7
@ Pacerier: Nun, sie wechseln nicht direkt zur Assemblersprache oder zum Maschinencode. In der Regel gehen sie zunächst zu einer maschinenunabhängigen Zwischendarstellung (Triples oder Quads) und analysieren diese zur Optimierung. Daraus generieren sie Montage- oder Maschinencode. Wenn Sie ein Buch über Compiler-Design (Aho & Ullman) in die Hand nehmen, werden Sie es bestimmt interessant finden.
Mike Dunlavey

1
Es ist wichtig anzumerken, dass das von ihm erstellte C ++ auch ein Bruchteil der Sprache war, die jetzt existiert. Es gab keine Vorlagen, keine neuen Bibliotheken, nur C-Casting und, wenn ich mich richtig erinnere, keine Ausnahmen.
Gort the Robot

2

Ich werde diese Antwort hinzufügen, da keine Antwort diesen Aspekt behandelt.

Sie benötigen technisch keine Software, um Code zu kompilieren. Solange Sie über die erforderlichen Compiler-Spezifikationen verfügen, können Sie die eigentliche Kompilierung manuell durchführen. So wurde nicht der erste C ++ - Compiler kompiliert. Ich sage nur, dass es möglich ist.

Vergleichen Sie mit Assemblersprache. Als sie in den frühen Tagen verwendet wurden, gab es keine Assembler-Software, die den Assembler-Code in Maschinencode umwandelte. Es wurde von Hand gemacht, aber die Assemblersprache gab den Programmierern einen besseren Überblick.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.