Die vorangegangenen Antworten geben so ziemlich die Erklärung, wenn auch meistens aus einem pragmatischen Blickwinkel, denn so sehr die Frage Sinn macht , wie es Raphaels Antwort vortrefflich erklärt .
Ergänzend zu dieser Antwort sollten wir beachten, dass C-Compiler heutzutage in C geschrieben sind. Natürlich können, wie Raphael bemerkt, ihre Ausgabe und ihre Leistung unter anderem von der CPU abhängen, auf der sie ausgeführt wird. Es kommt aber auch auf den Optimierungsgrad des Compilers an. Wenn Sie in C einen besser optimierenden Compiler für C schreiben (den Sie dann mit dem alten kompilieren, um ihn ausführen zu können), erhalten Sie einen neuen Compiler, der C zu einer schnelleren Sprache macht als zuvor. Also, was ist die Geschwindigkeit von C? Beachten Sie, dass Sie den neuen Compiler sogar in einem zweiten Durchgang mit sich selbst kompilieren können, so dass er effizienter kompiliert wird, obwohl Sie immer noch denselben Objektcode angeben. Und der Vollbeschäftigungssatz zeigt, dass solche Verbesserungen kein Ende haben (danke an Raphael für den Hinweis).
Ich denke jedoch, dass es sich lohnen kann, das Problem zu formalisieren, da es einige grundlegende Konzepte und insbesondere die denotationale und die operationelle Sichtweise der Dinge sehr gut illustriert.
Was ist ein Compiler?
Ein Compiler , abgekürzt mit wenn keine Mehrdeutigkeit vorliegt, ist eine Realisierung einer berechenbaren Funktion , die einen Programmtext eine Funktion berechnet , in einer geschriebenen Quellsprache in den Programmtext in einer schriftlichen
Zielsprache , wird das soll die gleiche Funktion berechnen .CS→TCCS→TP:SP SP:T TP
Aus semantischer Sicht, dh denotational , spielt es keine Rolle, wie diese Kompilierfunktion berechnet wird, dh welche Realisierung gewählt wird. Es könnte sogar durch ein magisches Orakel geschehen. Mathematisch ist die Funktion einfach eine Menge von Paaren .CS→TCS→T{(P:S,P:T)∣PS∈S∧PT∈T}
Die semantische Kompilierungsfunktion ist korrekt, wenn sowohl als auch dieselbe Funktion berechnen . Diese Formalisierung gilt jedoch auch für einen inkorrekten Compiler. Der einzige Punkt ist, dass alles, was implementiert wird, unabhängig von den Implementierungsmitteln das gleiche Ergebnis erzielt. Was semantisch zählt, ist, was vom Compiler gemacht wird, nicht wie (und wie schnell) es gemacht wird.CS→TPSPTP
Tatsächlich ist das Erhalten von von ein operationelles Problem, das gelöst werden muss. Aus diesem Grund muss die Kompilierungsfunktion eine berechenbare Funktion sein. Dann kann jede Sprache mit Turing-Power, egal wie langsam sie ist, Code so effizient produzieren wie jede andere Sprache, auch wenn dies möglicherweise weniger effizient ist.P:TP:SCS→T
Wenn wir das Argument verfeinern, möchten wir wahrscheinlich, dass der Compiler eine gute Effizienz aufweist, damit die Übersetzung in angemessener Zeit ausgeführt werden kann. Die Leistung des Compiler-Programms ist also für die Benutzer von Bedeutung, hat jedoch keinen Einfluss auf die Semantik. Ich sage Leistung, weil die theoretische Komplexität einiger Compiler viel höher sein kann, als man erwarten würde.
Über Bootstrapping
Dies wird die Unterscheidung veranschaulichen und eine praktische Anwendung zeigen.
Es ist nun üblich, zuerst eine Sprache mit einem Interpreter zu implementieren und dann einen Compiler in der Sprache selbst zu schreiben . Dieser Compiler kann mit dem Interpreter , um ein beliebiges Programm in ein Programm . Wir haben also einen laufenden Compiler von Sprache bis (Maschine?) Sprache , aber er ist sehr langsam, wenn auch nur, weil er auf einem Interpreter läuft.I S C S → TSIS S C S → TCS→T:SS I S P : S P : T STCS→T:SISP:SP:TST
Aber man kann diese Compilieren Anlage verwenden Sie den Compiler zu kompilieren
, da es in der Sprache geschrieben ist , und somit erhalten Sie einen Compiler geschrieben in die Zielsprache . Wenn Sie, wie so oft, davon ausgehen, dass eine Sprache ist, die effizienter interpretiert wird (z. B. maschinenneutral), erhalten Sie eine schnellere Version Ihres Compilers, die direkt in der Sprache . Es erledigt genau den gleichen Job (dh es produziert die gleichen Zielprogramme), aber es erledigt es effizienter. S C S → TCS→T:SS TTTCS→T:TTTT