#define cuadrado(x) x*x
Pero sin darnos cuenta hemos caído en una trampa terrible. En un primer intento nos damos cuenta que 2/cuadrado(10) no funciona porque se expande a 2/10*10. Para intentar solucionarlo cambiamos la macro a:
#define cuadrado(x) (x*x)
Acto seguido vemos como no funciona al intentar hacer cuadrado(1+1) porque se expande a (1+1*1+1). Así que intentamos volver a arreglar la macro:
#define cuadrado(x) ((x)*(x))
Pero así y todo nos sigue sin funcionar de forma correcta al hacer:
int x = 2;
cuadrado(x++)
cuadrado(x++)
Porque se expande a ((x++)*(x++)). Finalmente intentamos usar otra solución:
int temp_var;
#define cuadrado(x) (temp_var=(x); temp_var*temp_var)
Pero sólo nos funciona con números enteros así que nunca más podrás hacer cuadrado(3.5).
Para conseguir una versión de la macro que nos funcione de forma
correcta deberemos tirar de extensiones del lenguaje no estándar:
#define cuadrado(x) ({typedef xtype = x; xtype xval = x; xval * xval; })
Una simple macro que en un principio parecía que no
sería gran cosa nos ha obligado a usar extensiones del lenguaje que no
nos ofrecen ninguna garantía de continuidad ya que no son parte del
estándar. Pero es que el sistema de macros de C no acaba aquí, programar
una macro que haga algo tan simple como:
strswitch(exp) {
case “hola”: llamar_hola(); break;
case “adios”; llamar_adios(); break;
default: llamar_pordefecto(); break;
}
case “hola”: llamar_hola(); break;
case “adios”; llamar_adios(); break;
default: llamar_pordefecto(); break;
}
Es literalmente imposible de llevar a cabo en C.