La compilación de un programa C ++ implica tres pasos:
Preprocesamiento: el preprocesador toma un archivo de código fuente C ++ y se ocupa de las directivas #include
s, #define
sy otras preprocesadores. El resultado de este paso es un archivo C ++ "puro" sin directivas de preprocesador.
Compilación: el compilador toma la salida del preprocesador y produce un archivo objeto a partir de ella.
Vinculación: el vinculador toma los archivos de objetos producidos por el compilador y produce una biblioteca o un archivo ejecutable.
Preprocesamiento
El preprocesador maneja las directivas del preprocesador , como #include
y #define
. Es independiente de la sintaxis de C ++, por lo que debe usarse con cuidado.
Funciona en un archivo C ++ fuente a la vez mediante la sustitución de #include
directivas con el contenido de los archivos respectivos (que suele ser sólo declaraciones), haciendo la sustitución de macros ( #define
), y la selección de diferentes partes del texto en función de #if
, #ifdef
y #ifndef
directivas.
El preprocesador funciona en una secuencia de tokens de preprocesamiento. La sustitución de macros se define como el reemplazo de tokens por otros tokens (el operador ##
permite fusionar dos tokens cuando tiene sentido).
Después de todo esto, el preprocesador produce una única salida que es una secuencia de tokens que resultan de las transformaciones descritas anteriormente. También agrega algunos marcadores especiales que le dicen al compilador de dónde provino cada línea para que pueda usarlos para producir mensajes de error sensibles.
Se pueden producir algunos errores en esta etapa con un uso inteligente de las directivas #if
y #error
.
Compilacion
El paso de compilación se realiza en cada salida del preprocesador. El compilador analiza el código fuente puro de C ++ (ahora sin directivas de preprocesador) y lo convierte en código ensamblador. Luego invoca el back-end subyacente (ensamblador en la cadena de herramientas) que ensambla ese código en código de máquina produciendo un archivo binario real en algún formato (ELF, COFF, a.out, ...). Este archivo de objeto contiene el código compilado (en forma binaria) de los símbolos definidos en la entrada. Los símbolos en los archivos de objetos se denominan por su nombre.
Los archivos de objetos pueden referirse a símbolos que no están definidos. Este es el caso cuando utiliza una declaración y no proporciona una definición para ella. Al compilador no le importa esto, y felizmente producirá el archivo objeto siempre que el código fuente esté bien formado.
Los compiladores generalmente le permiten detener la compilación en este punto. Esto es muy útil porque con él puede compilar cada archivo de código fuente por separado. La ventaja que esto proporciona es que no necesita volver a compilar todo si solo cambia un solo archivo.
Los archivos de objetos producidos pueden colocarse en archivos especiales llamados bibliotecas estáticas, para facilitar su reutilización más adelante.
Es en esta etapa que se informan errores de compilador "regulares", como errores de sintaxis o errores de resolución de sobrecarga fallidos.
Enlace
El enlazador es lo que produce la salida de compilación final de los archivos de objetos que produjo el compilador. Este resultado puede ser una biblioteca compartida (o dinámica) (y aunque el nombre es similar, no tienen mucho en común con las bibliotecas estáticas mencionadas anteriormente) o un ejecutable.
Vincula todos los archivos de objetos reemplazando las referencias a símbolos indefinidos con las direcciones correctas. Cada uno de estos símbolos se puede definir en otros archivos de objetos o en bibliotecas. Si se definen en bibliotecas distintas de la biblioteca estándar, debe informar al vinculador sobre ellas.
En esta etapa, los errores más comunes son definiciones faltantes o definiciones duplicadas. Lo primero significa que las definiciones no existen (es decir, no están escritas) o que los archivos de objetos o las bibliotecas donde residen no se entregaron al vinculador. Esto último es obvio: el mismo símbolo se definió en dos archivos de objetos o bibliotecas diferentes.