Python tiene un compilador! Simplemente no lo notas porque se ejecuta automáticamente. Sin embargo, puede decir que está allí: mire los archivos .pyc
(o .pyo
si tiene el optimizador activado) que se generan para los módulos que usted import
.
Además, no se compila con el código de la máquina nativa. En cambio, se compila en un código de bytes que utiliza una máquina virtual. La máquina virtual es en sí misma un programa compilado. Esto es muy similar a cómo funciona Java; tan similar, de hecho, que hay una variante de Python ( Jython ) que compila el código de bytes de la máquina virtual Java. También está IronPython , que compila el CLR de Microsoft (utilizado por .NET). (El compilador de código de bytes de Python normal a veces se llama CPython para desambiguarlo de estas alternativas).
C ++ necesita exponer su proceso de compilación porque el lenguaje en sí está incompleto; no especifica todo lo que el enlazador necesita saber para construir su programa, ni puede especificar opciones de compilación de forma portátil (algunos compiladores le permiten usar #pragma
, pero eso no es estándar). Por lo tanto, debe hacer el resto del trabajo con archivos MAKE y posiblemente auto hell (autoconf / automake / libtool). Esto es realmente solo un remanente de cómo C lo hizo. Y C lo hizo así porque simplificó el compilador, que es una de las razones principales por la que es tan popular (cualquiera podría crear un compilador C simple en los años 80).
Algunas cosas que pueden afectar la operación del compilador o enlazador pero que no se especifican en la sintaxis de C o C ++:
- resolución de dependencia
- requisitos de la biblioteca externa (incluido el orden de dependencia)
- nivel optimizador
- ajustes de advertencia
- versión de especificación de idioma
- asignaciones de enlazador (qué sección va a dónde en el programa final)
- arquitectura objetivo
Algunos de estos se pueden detectar, pero no se pueden especificar; por ejemplo, puedo detectar con qué C ++ está en uso __cplusplus
, pero no puedo especificar que C ++ 98 sea el que se usa para mi código dentro del propio código; Tengo que pasarlo como una marca al compilador en el Makefile, o hacer una configuración en un diálogo.
Si bien puede pensar que existe un sistema de "resolución de dependencia" en el compilador, que genera automáticamente registros de dependencia, estos registros solo dicen qué archivos de encabezado utiliza un determinado archivo fuente. No pueden indicar qué módulos de código fuente adicionales se requieren para vincular a un programa ejecutable, porque no hay una forma estándar en C o C ++ para indicar que un archivo de encabezado dado es la definición de interfaz para otro módulo de código fuente en lugar de solo un montón de líneas que desea mostrar en varios lugares para que no se repita. Existen tradiciones en las convenciones de nomenclatura de archivos, pero el compilador y el vinculador no las conocen ni las aplican.
Varios de estos se pueden configurar usando #pragma
, pero esto no es estándar, y estaba hablando del estándar. Todas estas cosas podrían especificarse mediante un estándar, pero no han sido en interés de la compatibilidad con versiones anteriores. La sabiduría predominante es que los makefiles y los IDE no están rotos, así que no los arregles.
Python maneja todo esto en el lenguaje. Por ejemplo, import
especifica una dependencia de módulo explícita, implica el árbol de dependencia y los módulos no se dividen en encabezado y archivos de origen (es decir, interfaz e implementación).