Preprocesador
La fase previa a la compilación en C y C++ que procesa las líneas con #, como #include o #define, antes de compilar el código.
Antes de compilar, el preprocesador hace sustituciones de texto: #include copia el contenido de otro archivo y #define define constantes o macros que se reemplazan en el código.
Las macros son simples sustituciones sin comprobar tipos, así que pueden dar sorpresas. En C++ moderno se prefieren constexpr, funciones inline y plantillas.
Un ejemplo
#define PI 3.14159 hace que el preprocesador cambie cada PI del código por ese número antes de compilar.
Por qué importa
En C y C++ el preprocesador es lo primero que actúa sobre tu código, antes de que el compilador lo vea. No entiende el lenguaje: solo manipula texto según las directivas que empiezan por #. Por eso aparece en casi cualquier proyecto: #include <stdio.h> incorpora declaraciones de otros archivos, #define crea constantes y macros, y #ifdef o #if permiten compilar partes distintas según el sistema operativo o la configuración (depuración frente a producción).
Entenderlo explica muchos errores desconcertantes, como la «redefinición» de algo incluido dos veces. Para evitarla, los archivos de cabecera (.h) llevan guardas, un patrón de #ifndef, #define y #endif (o #pragma once en muchos compiladores) que impide procesar el mismo archivo más de una vez. También verás directivas del preprocesador en proyectos multiplataforma con código específico para Windows o Linux.
Confusiones frecuentes
Se confunde una macro con una función. Una macro es sustitución de texto, sin comprobar tipos, y puede dar resultados inesperados: #define CUADRADO(x) x*x con CUADRADO(2+3) se expande a 2+3*2+3, que vale 11 y no 25. La solución es poner paréntesis a todo (((x)*(x))), o mejor, usar una función inline o constexpr. Tampoco es lo mismo #define que una constante real (const): la primera no tiene tipo ni ámbito, y los mensajes de error pueden referirse a un texto ya sustituido que no aparece en tu código.
Preguntas frecuentes
¿Qué diferencia hay entre `#include <x.h>` y `#include "x.h"`?
Con ángulos se busca primero en las carpetas del sistema o del compilador, y con comillas primero en la carpeta de tu proyecto. Las comillas se usan para tus propios archivos.
¿Para qué sirve `#pragma once`?
Para que un archivo de cabecera se incluya una sola vez, como alternativa a las guardas con #ifndef. Lo admiten los compiladores habituales, aunque no es estándar.
Fuentes consultadas
- The C Preprocessor (GNU)
- Preprocessor (cppreference.com)