C Language Reemplazo de macros


Ejemplo

La forma más simple de reemplazo de macro es definir una manifest constant , como en

#define ARRSIZE 100
int array[ARRSIZE];

Esto define una macro similar a una función que multiplica una variable por 10 y almacena el nuevo valor:

#define TIMES10(A) ((A) *= 10)

double b = 34;
int c = 23;

TIMES10(b);   // good: ((b) *= 10);
TIMES10(c);   // good: ((c) *= 10);
TIMES10(5);   // bad:  ((5) *= 10);

El reemplazo se realiza antes de cualquier otra interpretación del texto del programa. En la primera llamada a TIMES10 el nombre A de la definición se reemplaza por b y el texto expandido se coloca en lugar de la llamada. Tenga en cuenta que esta definición de TIMES10 no es equivalente a

#define TIMES10(A) ((A) = (A) * 10)

porque esto podría evaluar el reemplazo de A , dos veces, lo que puede tener efectos secundarios no deseados.

Lo siguiente define una macro similar a una función cuyo valor es el máximo de sus argumentos. Tiene las ventajas de trabajar con cualquier tipo compatible de argumentos y de generar código en línea sin la sobrecarga de la función de llamada. Tiene las desventajas de evaluar uno u otro de sus argumentos por segunda vez (incluidos los efectos secundarios) y de generar más código que una función si se invoca varias veces.

#define max(a, b) ((a) > (b) ? (a) : (b))

int maxVal = max(11, 43);              /* 43 */
int maxValExpr = max(11 + 36, 51 - 7); /* 47 */

/* Should not be done, due to expression being evaluated twice */
int j = 0, i = 0;
int sideEffect = max(++i, ++j);       /* i == 4 */

Debido a esto, las macros que evalúan sus argumentos varias veces generalmente se evitan en el código de producción. Desde C11 existe la característica _Generic que permite evitar tales invocaciones múltiples.

Los abundantes paréntesis en las expansiones de macro (lado derecho de la definición) aseguran que los argumentos y la expresión resultante se unen correctamente y se ajusten bien al contexto en el que se llama la macro.