[C con Clase] duda con #defines

Steven Davidson steven en conclase.net
Jue Jun 21 06:58:30 CEST 2007


Hola Pamela,

El pasado 2007-06-21 03:56:06, Pato escribió:

P> Bien, muchas gracias Steven, muy clara tu explicación.

De nada; para eso estamos.

P> La duda que me surge es que he leído que el uso de macros no permite
P> la 'revisión de tipos' en el libro de Deitel, eso me sugiere que hay
P> una mejor forma de hacer lo mismo. La pregunta sería ¿cual es la
P> ventaja de hacerlo con esas macros complejas? ¿hay forma de hacerlo
P> más legible o portable aunque se pierda eficiencia?

Ciertamente, no es conveniente usar macros ni constantes simbólicas si podemos usar funciones y constantes, respectivamente. C++ introduce ciertos "mecanismos" o técnicas para usar el lenguaje para programar y no depender tanto de las directivas del precompilador.

Las constantes simbólicas pueden ser sustituidas por constantes. Por ejemplo,

#define NMAX 100
#define BUFTAM (1024*NMAX)
...
int *pLista = new int[NMAX];

Bajo C++, se puede reescribir lo anterior como:

const int NMAX = 100;
const int BUFTAM = 1024*NMAX;
...
int *pLista = new int[NMAX];

Para las macros, podemos usar funciones "en línea" o "in situ". Por ejemplo,

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

Bajo C++, escribimos:

inline int max( int a, int b )
{
 return a > b ? a : b;
}

Si queremos aceptar cualquier tipo de dato para los dos parámetros, entonces podemos usar funciones plantillas. Esto sería:

template< typename T >
inline T max( T a, T b )
{
 return a > b ? a : b;
}

Ahora podemos usar 'max()' con cualquier tipo de dato, con tal de que exista una definición para el operador > con este tipo de dato. Por ejemplo,

cout << max( 10, 200 );
cout << max( 1.23e10, .2034e-6 );
cout << max( 123123123L, 4549830912L );


Esto no significa que las macros y constantes simbólicas no se usen, sino que a la hora de programar, no tenemos que depender de ellas, si no son necesarias. Por ejemplo,

#ifndef _FICHERO_H_
#define _FICHERO_H_

#include <iostream>

#ifndef _VERSION_
#define _VERSION_ 0x0402
#endif

#define _ID_ #__FILE__ ";" #_VERSION_ ";" #__TIMESTAMP__

#endif

Lo anterior sería bastante engorroso si no usáramos el precompilador. Claro que podríamos reescribir la última constante simbólica como una constante, pero no su definición. Es decir,

const char _ID_[] = #__FILE__ ";" #_VERSION_ ";" #__TIME__;

Después del precompilador, acabaríamos con un código fuente como el siguiente:

const char _ID_[] = "fichero.h" ";" "0x0402" ";" "16:28:45";

que es lo mismo que,
const char _ID_[] = "fichero.h;0x0402;16:28:45";


Las macros también pueden sernos de mucha ayuda, pero si se puede describir su comportamiento como una función de C++, entonces escribe el código en C++.


Espero que todo esto te sirva.

Steven


Más información sobre la lista de distribución Cconclase