9.6. Más características del preprocesador

Antes, se dijo que casi siempre se prefiere usar funciones inline en lugar de macros del preprocesador. Las excepciones aparecen cuando necesita usar tres propiedades especiales del preprocesador de C (que es también el preprocesador de C++): conversión a cadena (stringizing), concatenación de cadenas, y encolado de símbolos (token pasting). La conversión a cadena, ya comentada anteriormente en el libro, se efectúa con la directiva # y permite tomar un identificador y convertirlo en una cadena de caracteres. La concatenación de cadenas tiene lugar cuando dos cadenas adyacentes no tienen signos de puntuación entre ellas, en cuyo caso se combinan. Estas dos propiedades son especialmente útiles cuando se escribe código de depuración. Así,

#define DEBUG(x) cout << #x " = " << x << endl

Esto imprime el valor de cualquier variable. Puede conseguir también una traza que imprima las sentencias tal como se ejecutan:

#define TRACE(s) cerr << #s << endl; s

El #s convierte a cadena la sentencia para la salida, y la segunda s repite la sentencia para que se ejecute. Por supuesto, este tipo de cosas pueden causar problemas, especialmente en bucles for de una única línea:

for(int i = 0; i < 100; i++)
     TRACE(f(i));

Como realmente hay dos sentencias en la macro TRACE(), el bucle for de una única línea ejecuta sólo la primera. La solución es reemplazar el punto y coma por una coma en la macro.

9.6.1. Encolado de símbolos

El encolado de símbolos, implementado con la directiva ##, es muy útil cuando se genera código. Permite coger dos identificadores y pegarlos juntos para crear un nuevo identificador automáticamente. Por ejemplo,

#define FIELD(a) char* a##_string; int a##_size
    class Record {
      FIELD(one);
      FIELD(two);
      FIELD(three);
      // ...
    };

Cada llamada a la macro FIELD() crea un identificador para una cadena de caracteres y otro para la longitud de dicha cadena. No sólo es más fácil de leer, sino que también puede eliminar errores de codificación y facilitar el mantenimiento.