Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
Pensar en C++ (Volumen 1) - Grupo ARCO
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
✐<br />
✐<br />
✐<br />
“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 254 — #292<br />
✐<br />
Capítulo 9. Funciones inline<br />
a = 12<br />
Cuando a es cuatro, sólo ocurre la primera parte de la condición, de modo que la<br />
expresión es evaluada sólo una vez, y el efecto resultante de la llamada a la macro es<br />
que a será 5, que es lo que se esperaría de una llamada a función normal <strong>en</strong> la misma<br />
situación. De todos modos, cuando el número está d<strong>en</strong>tro del rango, se evalúan<br />
ambas condiciones, lo que da como resultado un tercer increm<strong>en</strong>to. Una vez que el<br />
número se sale del rango, ambas condiciones sigu<strong>en</strong> si<strong>en</strong>do evaluadas de manera<br />
que se obti<strong>en</strong><strong>en</strong> dos increm<strong>en</strong>tos. Los efectos colaterales son distintos, dep<strong>en</strong>di<strong>en</strong>do<br />
del argum<strong>en</strong>to.<br />
Este no es desde luego el comportami<strong>en</strong>to que se quiere de una macro que se<br />
parece a una llamada a función. En este caso, la solución obviam<strong>en</strong>te es hacer una<br />
aut<strong>en</strong>tica función, lo que de hecho implica la cabecera extra y puede reducir la efici<strong>en</strong>cia<br />
si se llama demasiado a esa función. Desafortunadam<strong>en</strong>te, el problema no<br />
siempre será tan obvio, y sin saberlo. puede estar utilizando una librería que conti<strong>en</strong>e<br />
funciones y macros juntas, de modo que un problema como éste puede esconder<br />
errores difíciles de <strong>en</strong>contrar. Por ejemplo, la macro putc() de cstdio puede llegar<br />
a evaluar dos veces su segundo argum<strong>en</strong>to. Esto está especificado <strong>en</strong> el Estándar<br />
C. Además, la implem<strong>en</strong>tación descuidada de toupper() como una macro puede<br />
llegar a evaluar el argum<strong>en</strong>to más de una vez, lo que dará resultados inesperados<br />
con toupper(*p++) 1 .<br />
9.1.1. Macros y acceso<br />
Por supuesto, C requiere codificación cuidadosa y el uso de macros de preprocesador,<br />
y se podría hacer lo mismo <strong>en</strong> <strong>C++</strong> si no fuese por un problema: las macros<br />
no pose<strong>en</strong> el concepto de ámbito requerido con los métodos. El preprocesador simplem<strong>en</strong>te<br />
hace substitución de texto, de modo que no puede hacer algo como:<br />
class X{<br />
int i;<br />
public:<br />
#define VAL(X::i) // Error<br />
ni nada parecido. Además, no habría ninguna indicación del objeto al que se está<br />
refiri<strong>en</strong>do. Simplem<strong>en</strong>te no hay ninguna forma de expresar el ámbito de clase <strong>en</strong><br />
una macro. No habi<strong>en</strong>do ninguna alternativa difer<strong>en</strong>te a macros de preprocesador,<br />
los programadores se s<strong>en</strong>tirán t<strong>en</strong>tados de crear algunos atributos públicos por el<br />
bi<strong>en</strong> de la efici<strong>en</strong>cia, exponi<strong>en</strong>do así la implem<strong>en</strong>tación subyac<strong>en</strong>te e impidi<strong>en</strong>do<br />
cambios <strong>en</strong> esa implem<strong>en</strong>tación, así como eliminando la protección que proporciona<br />
private.<br />
9.2. Funciones inline<br />
Al resolver el problema que había <strong>en</strong> <strong>C++</strong> con las macros cuando acced<strong>en</strong> a miembros<br />
de clases privada, todos los problemas asociados con las macros de preprocesador<br />
fueron eliminados. Esto se ha hecho aplicando el concepto de macros bajo el control<br />
del compilador al cual pert<strong>en</strong>ec<strong>en</strong>. <strong>C++</strong> implem<strong>en</strong>ta la macro como una función<br />
inline, lo que es una función real <strong>en</strong> todo s<strong>en</strong>tido. Todo comportami<strong>en</strong>to esperado de<br />
1 Andrew Ko<strong>en</strong>ig <strong>en</strong>tra <strong>en</strong> más detalles <strong>en</strong> su libro C Traps & Pitfalls (Addison-Wesley, 1989).<br />
254<br />
✐<br />
✐<br />
✐<br />
✐