Python ma kompilator! Po prostu tego nie zauważasz, ponieważ działa automatycznie. Możesz jednak powiedzieć, że tam jest: spójrz na .pyc
(lub .pyo
jeśli masz włączony optymalizator) pliki, które są generowane dla modułów, które ty import
.
Ponadto nie kompiluje się do kodu natywnej maszyny. Zamiast tego kompiluje się do kodu bajtowego używanego przez maszynę wirtualną. Maszyna wirtualna sama jest skompilowanym programem. Jest to bardzo podobne do działania Java; tak podobny, że istnieje wariant Pythona ( Jython ), który zamiast tego kompiluje się do kodu bajtowego wirtualnej maszyny Java! Istnieje również IronPython , który kompiluje się do CLR Microsoftu (używanego przez .NET). (Zwykły kompilator bajtowy kodu w języku Python jest czasem nazywany CPython, aby odróżnić go od tych alternatyw).
C ++ musi ujawnić proces kompilacji, ponieważ sam język jest niekompletny; nie określa wszystkiego, co linker powinien wiedzieć, aby zbudować program, ani nie może określać opcji kompilacji przenośnie (niektóre kompilatory pozwalają #pragma
, ale nie jest to standard). Więc resztę pracy musisz wykonać przy użyciu plików makefile i ewentualnie automatycznego piekła (autoconf / automake / libtool). To jest naprawdę tylko relacja po tym, jak to zrobił C. C zrobił to w ten sposób, ponieważ uczynił kompilator prostym, co jest jednym z głównych powodów, dla których jest tak popularny (każdy mógł wypróbować prosty kompilator C w latach 80-tych).
Niektóre rzeczy, które mogą wpłynąć na działanie kompilatora lub linkera, ale nie są określone w składni C lub C ++:
- rozwiązywanie zależności
- wymagania dotyczące biblioteki zewnętrznej (w tym kolejność zależności)
- poziom optymalizatora
- ustawienia ostrzeżeń
- wersja specyfikacji języka
- mapowania linkerów (która sekcja idzie gdzie w ostatecznym programie)
- architektura docelowa
Niektóre z nich można wykryć, ale nie można ich określić; np. mogę wykryć, z którym C ++ jest używany __cplusplus
, ale nie mogę określić, że C ++ 98 jest tym, który jest używany dla mojego kodu w samym kodzie; Muszę przekazać go jako flagę do kompilatora w pliku Makefile lub wprowadzić ustawienia w oknie dialogowym.
Chociaż może się wydawać, że w kompilatorze istnieje system „rozwiązywania zależności”, który automatycznie generuje rekordy zależności, te rekordy mówią tylko, jakie pliki nagłówkowe wykorzystuje dany plik źródłowy. Nie mogą wskazać, jakie dodatkowe moduły kodu źródłowego są wymagane do połączenia się z programem wykonywalnym, ponieważ w C lub C ++ nie ma standardowego sposobu wskazania, że dany plik nagłówkowy jest definicją interfejsu dla innego modułu kodu źródłowego, a nie tylko wiersze, które chcesz wyświetlać w wielu miejscach, aby się nie powtarzać. Istnieją konwencje nazewnictwa plików, ale nie są one znane ani egzekwowane przez kompilator i linker.
Kilka z nich można ustawić za pomocą #pragma
, ale jest to niestandardowe i mówiłem o standardzie. Wszystkie te rzeczy mogą być określone przez standard, ale nie były w interesie kompatybilności wstecznej. Panuje przekonanie, że pliki makefile i IDE nie są zepsute, więc ich nie naprawiaj.
Python obsługuje to wszystko w języku. Na przykład import
określa jawną zależność modułu, implikuje drzewo zależności, a moduły nie są dzielone na pliki nagłówkowe i źródłowe (tj. Interfejs i implementacja).