El proceso de compilación de un programa C
El compilador del lenguaje C/C++ ejecuta tres etapas desde que se recibe el código fuente
(ejemplo.c) hasta que se tiene el código ejecutable (ejemplo.exe), listo para correr:
ejemplo.c Precompilación Compilación Enlazado ejemplo.exe
El entendimiento de estas tres etapas es fundamental para un adecuado desarrollo de un
programa en C y a menudo nos ahorrará dolores de cabeza. El proceso completo de compilación
se ilustra en la siguiente figura:
PRECOMPILACIÓN
En esta primera etapa se toma el archivo fuente y se realizan una serie de modificaciones, entre
ellas:
Se elimina cualquier comentario delimitado por los pares de símbolos /* */
Se buscan todos los archivos de encabezados (*.h) mencionados en el archivo fuente y se
copia el contenido de estos archivos en la posición exacta donde está la declaración
#include (de hecho #include no está limitado a que la extensión del archivo sea *.h, puede
ser cualquier otra)
Si existen sentencias #define se busca la aparición del símbolo que se definio y se sustituye
por el texto definido
Si existen sentencias #ifdef-#else-#endif estas determinan qué segmentos del programa
fuente se mantendrán cuáles se eliminarán a la salida de ésta primera etapa
M en C Gabriel Castillo Hernánez Facultad de Ingeniería, UNAM
La salida de este primer paso es un archivo fuente modificado: no contiene comentarios ni
sentencias tales como #define #include #ifdef, etc. Esta primera etapa no verifica sintaxis,
únicamente realiza modificaciones al código fuente. Llamemos a esta salida el archivo $$$.c
COMPILACIÓN
En esta etapa se toma la salida de la primera etapa ($$$.c) y se compila el código, durante el
proceso se verifica la sintaxis del programa y se generan los errores y las advertencias bastante
comunes durante el trabajo de programación.
La salida es un archivo con código binario (código objeto) pero incapaz de correr, debido
principalmente a que aún falta información para completar el programa, por ejemplo:
Aún no se sabe qué se debe hacer cuando se invoque a la función printf() o que se hace
cuando se llama una función scanf() .
De la misma manera es posible que aún no se sepa dónde están en memoria algunas
variables y otros elementos que son estándares en C y que el usuario no se preocupa por
definir, por ejemplo: stdin, stdout, etc.
ENLAZADO
También conocida como ligado o linkeado (derivada de linker, nombre en inglés con que se le
conoce al programa que realiza éste proceso), en este último paso se adjunta al código binario del
programa toda la información faltante y que forma parte de las funciones y variables estándares
del lenguaje C.
M en C Gabriel Castillo Hernánez Facultad de Ingeniería, UNAM
Por ejemplo si el código contiene una función printf() se agrega al código binario la sección del
código binario correspondiente al cuerpo de la función printf() tal como está definida por el
compilador.
La salida de este proceso el programa ejecutable.
COMPILACIÓN DE UN PROYECTO
En la práctica, los sistemas están constituidos por decenas de archivos fuentes, ya sea archivos de
código fuente (*.c) o archivos de encabezados (*.h), todos ellos escritos por el equipo
desarrollador. El proceso de compilación de un proyecto de éste tipo modifica un poco el esquema
planteado anteriormente, pero su esencia se mantiene.
El proceso de compilación de un proyecto comienza con el preprocesamiento de cada uno de los
archivos fuente y su posterior compilación, de manera que existirá un archivo con código binario
(*.obj) para cada archivo fuente. El siguiente paso es el enlazado de todos los archivos binarios
M en C Gabriel Castillo Hernánez Facultad de Ingeniería, UNAM
junto con las bibliotecas de funciones necesarias, de la misma manera que en el caso anterior al
archivo ejecutable se adjunta únicamente el código binarios de las funciones empleadas, por
ejemplo si nunca se emplea en el programa la función strcpy(), entonces el código binario de ésta
función no se adjunta al archivo ejecutable.
Algunas de las ventajas de haber dividido en varios archivos el sistema son:
Mayor control de código al agrupar funcionalidad similar en un solo archivo, por
ejemplo, funciones de entrada, funciones de salida, etc…
Si se realiza un cambio en algún archivo en particular, no es necesario recompilar
todo el sistema para generar nuevamente los archivos binarios (*.obj), la idea es
solo recompilar aquellos archivos fuente que se vean afectados por el cambio.
Facilidad de manejo del sistema, imagine usted que tiene que localizar un error en
un archivo con 25,000 líneas de código
M en C Gabriel Castillo Hernánez Facultad de Ingeniería, UNAM