Historia del tema:
Las macros provienen del lenguaje C como una poderosa herramienta para automatizar secciones de código repetitivas en la etapa de preprocesamiento. En C++, su uso ofreció flexibilidad, pero también trajo numerosos peligros ocultos debido a la falta de verificación de tipos y la confusión en el funcionamiento del preprocesador.
Problema:
Los principales riesgos del uso de macros son:
Solución:
En los estándares modernos de C++, se recomienda usar funciones inline, plantillas, constexpr, enum class, así como variables constexpr en lugar de macros.
Ejemplo de código:
// Malo: #define MAX(a, b) ((a) > (b) ? (a) : (b)) // Bueno: template<typename T> constexpr T max(T a, T b) { return a > b ? a : b; }
Características clave:
¿Puede una macro ser más peligrosa que una función inline?
Sí. Las macros no se ajustan a las reglas de sintaxis y tipos. Puede haber resultados inesperados al pasar parámetros con efectos secundarios.
#define SQUARE(x) ((x) * (x)) int y = 5; int z = SQUARE(y++); // y se incrementa dos veces!
¿Es #include también una macro?
No, #include es una directiva del preprocesador, pero el uso de macros y include está relacionado: a través de una macro se puede modificar la lista de archivos incluidos (extremadamente desaconsejado).
¿Se puede depurar una macro como una función normal?
No, el depurador descompone la macro y muestra el texto ya sustituido, no hay entidades nombradas separadas.
En el código antiguo se definieron numerosos macros de cálculo con efectos (por ejemplo, incremento), lo que llevó a errores difíciles de detectar al utilizar nuevas funciones.
Pros:
Contras:
Al refactorizar, los macros fueron reemplazados por funciones de plantillas y constexpr, y se aplicó enum class en lugar de macros de bandera.
Pros:
Contras: