Operadores especiales '#' y '##' dentro de definiciones #define

Dentro de las definiciones de macros se pueden utilizar dos operadores especiales:

  • Un único símbolo de almohadilla '#' delante del nombre de un parámetro de macro convierte el contenido de ese parámetro en una cadena; sólo se permite en macros de función;
  • Un doble símbolo hash '##' entre dos palabras (tokens) las combina, y si el token es un parámetro de macro, se sustituye su valor, pero si el token es un nombre de macro, se sustituye tal cual, sin expandir la macro; si como resultado del «pegado» se obtiene otro nombre de macro, se expande.

En los ejemplos de este libro, a menudo utilizamos la siguiente macro:

#define PRT(APrint(#A"=", (A))

Llama a la función Print , en la que la expresión pasada se muestra como una cadena gracias a #A, y tras el signo «igual» se imprime el valor real de A.

Para demostrar '##', analicemos otra macro:

#define COMBINE(A,B,XA##B(X)

Con ella podemos generar de hecho una llamada a la macro SQN definida arriba:

Print(COMBINE(SQ,N,2)); // 4

Los literales SQ y N se concatenan, tras lo cual la macro SQN se expande a ((2)*(2)) y produce el resultado 4.

La siguiente macro le permite crear una definición de variable en el código generando su nombre dados los parámetros de la macro:

#define VAR(TYPE,NTYPE var##N = N

A continuación, la línea de código

VAR(int3);

equivale a lo siguiente:

int var3 = 3;

La concatenación de tokens permite la implementación de un bucle abreviado sobre los elementos del array utilizando una macro.

#define for_each(IAfor(int I = 0max_##I = ArraySize(A); I < max_##I; ++I)
  
// describe and somehow fill in the array x
double x[];
// ...
// implement loop through the array
for_each(ix)
{
   x[i] = i * i;
}