13.01.2015 Views

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

SHOW MORE
SHOW LESS

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 />

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!