Предыдущие ответы дают в значительной степени объяснение, хотя в основном с прагматической точки зрения, поскольку вопрос имеет смысл , что превосходно объясняется ответом Рафаэля .
В дополнение к этому ответу мы должны отметить, что в настоящее время компиляторы C написаны на C. Конечно, как отметил Рафаэль, их вывод и его производительность могут зависеть, помимо прочего, от процессора, на котором он работает. Но это также зависит от объема оптимизации, выполненной компилятором. Если вы напишите в C лучший оптимизирующий компилятор для C (который вы затем скомпилируете со старым, чтобы иметь возможность его запускать), вы получите новый компилятор, который делает C более быстрым языком, чем это было раньше. Итак, какова скорость С? Обратите внимание, что вы можете даже скомпилировать новый компилятор с самим собой в качестве второго прохода, чтобы он компилировался более эффективно, хотя все еще предоставлял тот же объектный код. И теорема о полной занятости показывает, что этим улучшениям нет конца (спасибо Рафаэлю за указатель).
Но я думаю, что, возможно, стоит попытаться формализовать проблему, так как она очень хорошо иллюстрирует некоторые фундаментальные концепции, и особенно концептуальный и функциональный взгляд на вещи.
Что такое компилятор?
Компилятор , сокращенно до если нет двусмысленности, является реализацией вычислимой функции которая будет переводить программный текст вычисляющий функцию , написанный на языке источника в текст программы , написанной на
целевом языке , который должен вычислить ту же функцию .CS→TCCS→TP:SP SP:T TP
С семантической точки зрения, т.е. denotationally , это не имеет значения , как эта функция компиляции вычисляется, т.е. то, что реализация выбрана. Это может быть даже сделано волшебным оракулом. Математически, функция - это просто набор пар .CS→TCS→T{(P:S,P:T)∣PS∈S∧PT∈T}
Семантическая функция компилирование является правильным , если оба и вычислить ту же самую функцию . Но эта формализация применима и к некорректному компилятору. Единственный момент заключается в том, что независимо от того, что реализовано, достигается тот же результат независимо от средств реализации. Семантически важно то, что делается компилятором, а не то, как (и как быстро) это делается.CS→TPSPTP
На самом деле получение из является оперативной проблемой, которая должна быть решена. Вот почему функция компиляции должна быть вычислимой функцией. Тогда любой язык, обладающий мощью Тьюринга, независимо от того, насколько он медленный, обязательно сможет создавать код, столь же эффективный, как и любой другой язык, даже если он может делать это менее эффективно.P:TP:SCS→T
Уточняя аргумент, мы, вероятно, хотим, чтобы компилятор имел хорошую эффективность, чтобы перевод мог быть выполнен в разумные сроки. Таким образом, производительность программы компилятора важна для пользователей, но не влияет на семантику. Я говорю о производительности, потому что теоретическая сложность некоторых компиляторов может быть намного выше, чем можно было бы ожидать.
О начальной загрузке
Это проиллюстрирует различие и покажет практическое применение.
В настоящее время общее место , чтобы сначала осуществить язык с переводчиком , а затем написать компилятор в языке самой. Этот компилятор может быть запущен с интерпретатором для преобразования любой программы в программу . Таким образом, у нас есть работающий компилятор с языка на (машинный?) Язык , но он очень медленный, хотя бы потому, что работает поверх интерпретатора.I S C S → TSIS S C S → TCS→T:SS I S P : S P : T STCS→T:SISP:SP:TST
Но вы можете использовать это средство компиляции для компиляции компилятора
, поскольку он написан на языке , и, таким образом, вы получите компилятор написанный на целевой язык . Если предположить, как это часто бывает, что является язык , который более эффективно интерпретировать (машинный родной, например), то вы получите более быструю версию компилятора работает непосредственно на языке . Он выполняет точно такую же работу (т. Е. Производит те же целевые программы), но делает это более эффективно. S C S → TCS→T:SS TTTCS→T:TTTT