Volver a la lista

Proceso de compilación: del código fuente al ejecutable.

Se comprende la diferencia entre compiladores e intérpretes, el proceso de conversión de código fuente a código máquina y las etapas del proceso de construcción (build).

Principiante
|
10min
|
Verificado (2026-07)
compilaciónintérpretecódigo máquinacódigo fuenteproceso de build
Progreso0/23 (0%)

Proceso de compilación — Desde el código fuente hasta el ejecutable

Al finalizar este tema

Podrás explicar la diferencia entre un compilador y un intérprete, comprender las etapas de conversión del código fuente a lenguaje de máquina y saber cómo se ejecutan Python, JavaScript y C, respectivamente.


La computadora no puede leer el código fuente

El código que escribimos es texto para humanos.

python
print("Hello, World!")

Lo que entiende la CPU es el lenguaje de máquina: instrucciones compuestas por 0 y 1.

text
10110000 01001000  (mov al, 'H')
11001101 00100001  (int 21h)

Es necesaria la conversión del código fuente a código máquina. Los programas que realizan esta conversión son el compilador y el intérprete.


Compilador vs. Intérprete

CompiladorIntérprete
Momento de la conversiónConvierte todo de una vez antes de la ejecuciónConvierte línea por línea durante la ejecución
ResultadoArchivo ejecutable (binario)Ninguno (ejecución inmediata)
Detección de erroresMuestra todos los errores en el momento de la compilaciónEl error se detecta al ejecutar la línea correspondiente
Velocidad de ejecuciónRápida (ya está convertido)Relativamente lenta
Lenguajes representativosC, C++, Rust, GoPython, JavaScript, Ruby

Analogía: el compilador es como la traducción de un libro (se traduce todo primero y luego se publica), mientras que el intérprete es como la interpretación simultánea (se traduce al instante mientras se habla).


Etapas de la compilación — En el caso de C

El proceso por el cual el código C se convierte en un archivo ejecutable:

text
Código fuente (.c)
    ↓ Preprocesado (Preprocessing)
Código preprocesado
    ↓ Compilación (Compilation)
Código ensamblador (.s)
    ↓ Ensamblado (Assembly)
Archivo objeto (.o)
    ↓ Enlazado (Linking)
Ejecutable (a.out / .exe)

1. Preprocesamiento

c
#include <stdio.h>
#define MAX 100

int main() {
    printf("Max is %d\n", MAX);
}

Reemplace #include con el contenido real del archivo de cabecera y sustituya #define por su valor. Esta etapa es una sustitución de texto.

2. Compilación (Compilation)

Analiza el código preprocesado y lo convierte en código ensamblador. Los errores de sintaxis se detectan en esta etapa.

asm
mov    edi, OFFSET FLAT:.LC0
mov    esi, 100
call   printf

3. Ensamblado

Convierte el código de ensamblador en lenguaje máquina (instrucciones binarias). El resultado es un archivo objeto (.o).

4. Enlace

Combina varios archivos objeto y bibliotecas en un único archivo ejecutable. Dado que la implementación real de printf se encuentra en la biblioteca estándar de C, el enlazador se encarga de conectarla.

bash
# GCC realiza todos estos pasos de una vez
gcc hello.c -o hello
./hello

¿Cómo se ejecuta Python?

Python es un modelo híbrido de compilación e interpretación.

text
Código fuente (.py)
    ↓ Compilador de Python
Bytecode (.pyc)
    ↓ Máquina virtual de Python (PVM)
Resultado de ejecución
python
# Inspecciona el bytecode
import dis
def add(a, b):
return a + b
dis.dis(add)
# LOAD_FAST 0 (a)
# LOAD_FAST 1 (b)
# BINARY_ADD
# RETURN_VALUE

El bytecode no es lenguaje máquina. Un intérprete llamado Python Virtual Machine (PVM) ejecuta el bytecode línea por línea. Es más lento que cuando la CPU lo ejecuta directamente como en C, pero puede ejecutarse independientemente del sistema operativo.

__pycache__/ habrás visto que se crea un archivo .pyc en la carpeta. Este es el caché de bytecode. Si el código fuente no cambia, se utiliza el caché sin necesidad de recompilar.


Cómo se ejecuta JavaScript

Los motores de JavaScript (V8, SpiderMonkey) utilizan compilación JIT (Just-In-Time).

text
Código fuente (.js)
    ↓ Análisis sintáctico
AST (árbol de sintaxis abstracta)
    ↓ Intérprete
Ejecución de bytecode (lenta)
    ↓ Compilador JIT (detecta código ejecutado con frecuencia)
Conversión a código máquina (rápida)

Al principio, se inicia la ejecución rápidamente mediante un intérprete y, cuando detecta que "esta función se ha llamado 1,000 veces", compila únicamente esa parte a código máquina. Dado que la compilación ocurre durante la ejecución, se denomina "Just-In-Time".


Java — El híbrido clásico entre compilación e interpretación

Java es similar a Python, pero más complejo.

text
Código fuente (.java)
    ↓ javac (compilación)
Bytecode (.class)
    ↓ JVM (Java Virtual Machine)
    ├── Intérprete (al principio)
    └── Compilador JIT (código ejecutado con frecuencia)
    ↓
Ejecución de código máquina
java
// Hello.java
public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
bash
javac Hello.java # Genera bytecode (.class)
java Hello # La JVM ejecuta el bytecode

"Escribir una vez, ejecutar en cualquier lugar": el bytecode de Java se ejecuta en cualquier lugar que tenga una JVM. Un archivo .class compilado en Windows también funciona en una JVM de Linux.


Tipos estáticos vs. tipos dinámicos

El sistema de tipos es un concepto estrechamente relacionado con la compilación.

c
// C: tipado estático; comprueba tipos durante la compilación
int x = 42;
x = "hello";  // ¡Error de compilación!
python
# Python: tipado dinámico; comprueba tipos durante la ejecución
x = 42
x = "hello" # OK: el tipo cambia durante la ejecución
Tipado estáticoTipado dinámico
Momento de verificación de tiposEn compilaciónEn ejecución
Detección de erroresAntes de la ejecuciónDurante la ejecución
Declaración de tiposObligatoria (int x)No es necesaria (x = 42)
Velocidad de ejecuciónRápidaRelativamente lenta
Lenguajes representativosC, Java, TypeScriptPython, JavaScript, Ruby

Implicaciones prácticas

text
¿Por qué Python es más lento que C?
→ C: la CPU ejecuta directamente el código máquina
→ Python: la máquina virtual interpreta y ejecuta el bytecode instrucción por instrucción

¿Por qué usar TypeScript?
→ Añade tipos estáticos a JavaScript y detecta errores antes de ejecutar
→ TypeScript → (compilación tsc) → JavaScript → (ejecución V8)

¿Por qué las imágenes Docker difieren según el sistema operativo?
→ Los binarios compilados dependen de la arquitectura de CPU, como x86 o ARM
→ Un binario para macOS no puede ejecutarse en Linux

Resumen clave

ConceptoResumen
CompiladorConvierte todo el código fuente a código máquina de antemano. Ejecución rápida
IntérpreteInterpreta y ejecuta línea por línea. Desarrollo rápido
BytecodeForma intermedia. Ejecutado por una máquina virtual (Python, Java)
JITCompila a código máquina solo las partes que se usan con frecuencia durante la ejecución (JavaScript)
Tipado estáticoVerifica los tipos en tiempo de compilación (C, TypeScript)
Tipado dinámicoVerifica los tipos en tiempo de ejecución (Python, JavaScript)

Herramientas de construcción y transpiladores

En el desarrollo moderno, además de la compilación e interpretación "puras", existen diversas herramientas de transformación.

text
TypeScript → (tsc) → JavaScript → (V8) → ejecución
JSX/React  → (Babel) → JavaScript → (V8) → ejecución
Sass/SCSS  → (sass) → CSS → renderizado del navegador

El transpilador realiza una conversión entre lenguajes del mismo nivel. Mientras que un compilador realiza una conversión de alto nivel a bajo nivel, un transpilador realiza una conversión de alto nivel a alto nivel. Los ejemplos más representativos son TypeScript→JavaScript y ES6→ES5.


Decir que "Python es un lenguaje interpretado" es solo parcialmente correcto: se compila a bytecode y luego se interpreta. Decir que "JavaScript es un lenguaje interpretado" también es solo parcialmente correcto: V8 realiza compilación JIT. Los lenguajes modernos combinan la compilación y la interpretación para buscar tanto la facilidad de desarrollo como el rendimiento de ejecución.


💬 Preguntas y comentarios

0 comentarios

Puedes publicar sin iniciar sesión. Los comentarios de invitados no pueden editarse ni eliminarse después.

0/2000

Cargando...