Attention! Your ePaper is waiting for publication!
By publishing your document, the content will be optimally indexed by Google via AI and sorted into the right category for over 500 million ePaper readers on YUMPU.
This will ensure high visibility and many readers!
El problema anterior puede solucionarse programando cuidadosam<strong>en</strong>te: poner<br />
<strong>en</strong>tre paréntesis todo lo que esté definido d<strong>en</strong>tro de una macro. De todos modos el<br />
segundo problema es más sutil. Al contrario de una función normal, cada vez que<br />
usa argum<strong>en</strong>tos <strong>en</strong> una macro, dicho argum<strong>en</strong>to es evaluado. Mi<strong>en</strong>tras la macro sea<br />
llamada solo con variables corri<strong>en</strong>tes, esta evaluación es b<strong>en</strong>igna, pero si la evaluación<br />
de un argum<strong>en</strong>to ti<strong>en</strong>e efectos secundarios, <strong>en</strong>tonces los resultados pued<strong>en</strong> ser<br />
inesperados y definitivam<strong>en</strong>te no imitaran el comportami<strong>en</strong>to de una función.<br />
Por ejemplo, esta macro determina si un argum<strong>en</strong>to <strong>en</strong>tra d<strong>en</strong>tro de cierto rango:<br />
✐ ✐ ✐ “Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 252 — #290 ✐ Capítulo 9. Funciones inline Ahora, si hacemos una llamada a F de esta manera: F(1) El preprocesador la expande de manera inesperada: (x) (x + 1)(1) El problema se debe al espacio <strong>en</strong>tre `F` y su paréntesis de apertura <strong>en</strong> la definición de la macro. Cuando el espacio es eliminado <strong>en</strong> el código de la macro, puedes llamar a la función incluso incluy<strong>en</strong>do el espacio. F (1) Y se expandirá de manera correcta a lo sigui<strong>en</strong>te: (1 + 1) El ejemplo anterior es un poco trivial y el problema es demasiado evid<strong>en</strong>te. Las dificultades reales ocurr<strong>en</strong> cuando se usan expresiones como argum<strong>en</strong>tos <strong>en</strong> llamadas a macros. Hay dos problemas. El primero es que las expresiones pued<strong>en</strong> expandirse d<strong>en</strong>tro de la macro de modo que la preced<strong>en</strong>cia de la evaluación es difer<strong>en</strong>te a lo que cabría esperar. Por ejemplo: #define FLOOR(x,b) x>=b0:1 Ahora, si usamos expresiones como argum<strong>en</strong>tos: if (FLOOR(a&0x0f,0x07)) // ... La macro se expandiría a: if (a&0x0f>=0x070:1) La preced<strong>en</strong>cia del & es m<strong>en</strong>or que la del >=, de modo que la evaluación de la macro te sorpr<strong>en</strong>derá. Una vez hayas descubierto el problema, puedes solucionarlo insertando paréntesis a todo lo que hay d<strong>en</strong>tro de la definición de la macro. (Este es un bu<strong>en</strong> método a seguir cuando defina macros de preprocesador), algo como: #define FLOOR(x,b) ((x)>=(b)0:1) De cualquier manera, descubrir el problema puede ser difícil, y no dará con él hasta después de haber dado por s<strong>en</strong>tado el comportami<strong>en</strong>to de la macro <strong>en</strong> sí misma. En la versión sin paréntesis de la macro anterior, la mayoría de las expresiones van a actuar de manera correcta a causa de la preced<strong>en</strong>cia de >=, que es m<strong>en</strong>or que la mayoría de los operadores como +, /, --, e incluso los operadores de desplazami<strong>en</strong>to. Por lo que puede p<strong>en</strong>sar que funciona con todas las expresiones, incluy<strong>en</strong>do aquellas que emple<strong>en</strong> operadores lógicos a nivel de bit. 252 ✐ ✐ ✐ ✐
✐ ✐ ✐ “Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 253 — #291 ✐ 9.1. Los peligros del preprocesador El problema anterior puede solucionarse programando cuidadosam<strong>en</strong>te: poner <strong>en</strong>tre paréntesis todo lo que esté definido d<strong>en</strong>tro de una macro. De todos modos el segundo problema es más sutil. Al contrario de una función normal, cada vez que usa argum<strong>en</strong>tos <strong>en</strong> una macro, dicho argum<strong>en</strong>to es evaluado. Mi<strong>en</strong>tras la macro sea llamada solo con variables corri<strong>en</strong>tes, esta evaluación es b<strong>en</strong>igna, pero si la evaluación de un argum<strong>en</strong>to ti<strong>en</strong>e efectos secundarios, <strong>en</strong>tonces los resultados pued<strong>en</strong> ser inesperados y definitivam<strong>en</strong>te no imitaran el comportami<strong>en</strong>to de una función. Por ejemplo, esta macro determina si un argum<strong>en</strong>to <strong>en</strong>tra d<strong>en</strong>tro de cierto rango: #define BAND(x) (((x)>5 && (x)5 && (x)