El proceso de compilación de un programa en C consta de varias etapas: preprocesamiento (preprocessing), compilación (compilation), ensamblaje (assembling), y enlace (linking). Históricamente, este esquema ha permitido dividir responsabilidades entre herramientas y facilitar el mantenimiento y la configuración del proceso de construcción.
Problema: Si no se comprende cómo funciona cada etapa, se pueden enfrentar a errores como "referencia indefinida", duplicación de código, errores poco evidentes debido al uso incorrecto de macros y problemas al escalar el código a múltiples archivos.
Solución: Es necesario entender que cada etapa cumple una función específica: el preprocesador procesa directivas como #define, #include y otras, el compilador traduce el código fuente en C a ensamblador, el ensamblador a código máquina, y el enlazador combina todos los archivos objeto y bibliotecas en un archivo ejecutable final.
Ejemplo de código:
Fragmento de código fuente:
#include <stdio.h> #define PI 3.14 int main() { printf("%f ", PI); return 0; }
Ejemplo de llamada a gcc con especificación explícita de etapas:
gcc -E program.c # Preprocesamiento gcc -S program.c # Compilación (hasta ensamblador) gcc -c program.c # Ensamblaje (hasta archivo objeto) gcc program.o -o prog # Enlace (linking)
Características clave:
¿Qué hace la directiva #include "file.h" en la etapa de compilación?
#Include inserta el contenido del archivo directamente en el lugar de la llamada durante la etapa de preprocesamiento, antes de que comience la compilación. Si se incluye el mismo archivo dos veces, esto puede llevar a definiciones múltiples de objetos o errores en el enlace.
¿Siempre es suficiente la definición de una función en un archivo para utilizarla en otro?
No, se necesita una declaración (prototipo) en el archivo de cabecera o al menos una declaración extern. De lo contrario, pueden ocurrir errores como "declaración implícita de función" o "referencia indefinida" durante el enlace.
¿Se pueden usar variables declaradas como static desde otro archivo?
No. static limita el ámbito de la variable o función al archivo actual. Esto significa que tales símbolos no son visibles para el enlazador en otros archivos objeto.
Un principiante implementa una función con el mismo nombre en dos archivos fuente. En la etapa de enlace, aparece un error extraño "definición múltiple de función".
Ventajas:
Desventajas:
Creación de archivos .h solo para declaraciones, archivos .c para definiciones. Uso de #ifdef para proteger archivos de cabecera. Todos los archivos se combinan a través del enlazador en el programa final.
Ventajas:
Desventajas: