У Python есть компилятор! Вы просто не замечаете этого, потому что он запускается автоматически. Однако вы можете сказать, что он там: посмотрите на .pyc
(или, .pyo
если у вас включен оптимизатор) файлы, сгенерированные для ваших модулей import
.
Кроме того, он не компилируется в код родной машины. Вместо этого он компилируется в байт-код, который используется виртуальной машиной. Виртуальная машина сама является скомпилированной программой. Это очень похоже на работу Java; настолько похоже, что фактически существует вариант Python ( Jython ), который вместо этого компилируется в байт-код виртуальной машины Java! Есть также IronPython , который компилируется в CLR от Microsoft (используется .NET). (Обычный компилятор байт-кода Python иногда называется CPython для устранения неоднозначности этого варианта.)
C ++ должен раскрыть процесс компиляции, потому что сам язык неполон; он не определяет все, что должен знать компоновщик для сборки вашей программы, и не может указывать параметры компиляции переносимо (некоторые компиляторы позволяют вам использовать #pragma
, но это не стандартно). Таким образом, вы должны выполнить остальную часть работы с make-файлами и, возможно, с auto hell (autoconf / automake / libtool). Это действительно просто пережиток того, как С это сделал. И C сделал это таким образом, потому что это сделало компилятор простым, что является одной из основных причин его популярности (любой мог запустить простой C-компилятор в 80-х годах).
Некоторые вещи, которые могут повлиять на работу компилятора или компоновщика, но не указаны в синтаксисе C или C ++:
- разрешение зависимостей
- требования к внешней библиотеке (включая порядок зависимостей)
- уровень оптимизатора
- настройки предупреждений
- версия спецификации языка
- сопоставления компоновщика (какой раздел находится в финальной программе)
- целевая архитектура
Некоторые из них могут быть обнаружены, но не могут быть указаны; например, я могу определить, с каким C ++ используется __cplusplus
, но я не могу указать, что C ++ 98 - это тот, который используется для моего кода в самом коде; Я должен передать его как флаг компилятору в Makefile или сделать настройку в диалоге.
Хотя вы можете подумать, что в компиляторе существует система «разрешения зависимостей», автоматически генерирующая записи зависимостей, эти записи только говорят, какие заголовочные файлы использует данный исходный файл. Они не могут указать, какие дополнительные модули исходного кода требуются для связи в исполняемой программе, поскольку в C или C ++ нет стандартного способа указать, что данный заголовочный файл является определением интерфейса для другого модуля исходного кода, а не просто набором линии, которые вы хотите показать в нескольких местах, чтобы не повторяться. Существуют традиции в соглашениях об именах файлов, но они не известны или не применяются компилятором и компоновщиком.
Некоторые из них могут быть установлены с использованием #pragma
, но это нестандартно, и я говорил о стандарте. Все эти вещи могут быть определены стандартом, но не в интересах обратной совместимости. Преобладающая мудрость заключается в том, что make-файлы и IDE не сломаны, поэтому не исправляйте их.
Python обрабатывает все это на языке. Например, import
указывает явную зависимость модуля, подразумевает дерево зависимостей, а модули не разделяются на заголовочные и исходные файлы (т. Е. Интерфейс и реализацию).