Discussion:
Una pregunta sobre Defines...
(demasiado antiguo para responder)
Juan Llanos
2004-05-12 22:10:13 UTC
Permalink
Cuando aprendi algo de C no me dieron nada de defines y ahora "me obligan" a
usar un define que otra persona ha creado y no tengo ni idea de como
interpretarlo... bueno un poco si, pero me lio con el ; y con \

#define TIEMPO_EVENTO(reloj) reloj=time(NULL)

#define IMPR_EVENTO_HILO(flujo_salida, reloj, tipoHilo, hilo, temporal_mens,
macro_mensaje)\
TIEMPO_EVENTO(reloj);sprintf(temporal_mens, macro_mensaje);\
fprintf(flujo_salida, "%s, Hilo %s: %d, %s\n",ctime(&reloj), tipoHilo,
hilo, temporal_mens)


Yo "entiendo" IMPR_EVENTO_HILO imprime algo haciendo uso del fprint y con
los parametros, pero me lio un poco con las dos funciones anteriores...

Pues eso. Gracias.
Julián Albo
2004-05-13 14:28:47 UTC
Permalink
Post by Juan Llanos
#define TIEMPO_EVENTO(reloj) reloj=time(NULL)
#define IMPR_EVENTO_HILO(flujo_salida, reloj, tipoHilo, hilo,
#temporal_mens,
macro_mensaje)\
TIEMPO_EVENTO(reloj);sprintf(temporal_mens, macro_mensaje);\
fprintf(flujo_salida, "%s, Hilo %s: %d, %s\n",ctime(&reloj), tipoHilo,
hilo, temporal_mens)
Yo "entiendo" IMPR_EVENTO_HILO imprime algo haciendo uso del fprint y con
los parametros, pero me lio un poco con las dos funciones anteriores...
Escribe un programa lo más pequeño posible que use esa macro (copiando de un
programa existente, si no sabes bien como llamarla) y pásalo por el
preprocesador de C (el comando cpp, suele ser). Así verás como queda una
vez expandido.

LO siguiente que habría que hacer sería tirar a la basura esa macro y
escribir una función que haga el trabajo.
--
Salu2
Juan Llanos
2004-05-13 15:48:50 UTC
Permalink
Post by Julián Albo
LO siguiente que habría que hacer sería tirar a la basura esa macro y
escribir una función que haga el trabajo.
A base de prueba y error lo he medio entendido... La verdad es que no me
gusta esa macro pero porque no la he hecho yo. De forma objetiva ¿esta mal
hecha? no se lo pienso decir al profesor pues tengo esperanzas de aprobar XD
Julián Albo
2004-05-13 16:12:36 UTC
Permalink
Post by Juan Llanos
A base de prueba y error lo he medio entendido... La verdad es que no me
gusta esa macro pero porque no la he hecho yo. De forma objetiva ¿esta mal
hecha? no se lo pienso decir al profesor pues tengo esperanzas de aprobar XD
Ante todo las macros cuanto menos se usen mejor, y en este caso particular
no veo ningún motivo para usar una macro, cualquier posible ganancia de
posibilidad ni se notará.
--
Salu2
Antoine Leca
2004-05-13 17:34:38 UTC
Permalink
De forma objetiva ¿esta mal hecha?
Pués, hay cositas que no son muy recomendable. Como:
- no poner el parametro reloj entre parentesis
- poner una asignación como macro, sin parentesis
- tener un macro con 6 argumentos, de los cual 2 son variables para declarar
(eso, jamas visto)
- hacer una llamada a sprintf sin sentido (strcpy lo hace mucho mejor),
enmascarada (sprintf es perillosa, puede desbordar), sin controlar el
resultado

No soy contrario a los macros en general. Pero está me parece más un
ejercicio de (muy malo) estilo que cualquiera cosa. Por supuesto la
remplacaría cuanto antes por una función. De todas maneras, con una llamada
a sprintf y una a fprintf, no hay criterios de velocidad ;-). Y con el
formato más suave de una función, leyendola despaciamente, se notaría que la
llamada a sprintf podría eventualamente ahorrarse... (es decir, si no se
utiliza despues el contenido de temporal_mens)


Antoine
Martin J. Sanchez
2004-05-14 10:07:04 UTC
Permalink
On Thu, 13 May 2004 00:10:13 +0200, "Juan Llanos"
Post by Juan Llanos
Cuando aprendi algo de C no me dieron nada de defines y ahora "me obligan" a
usar un define que otra persona ha creado y no tengo ni idea de como
interpretarlo... bueno un poco si, pero me lio con el ; y con \
#define TIEMPO_EVENTO(reloj) reloj=time(NULL)
#define IMPR_EVENTO_HILO(flujo_salida, reloj, tipoHilo, hilo, temporal_mens,
macro_mensaje)\
TIEMPO_EVENTO(reloj);sprintf(temporal_mens, macro_mensaje);\
fprintf(flujo_salida, "%s, Hilo %s: %d, %s\n",ctime(&reloj), tipoHilo,
hilo, temporal_mens)
Yo "entiendo" IMPR_EVENTO_HILO imprime algo haciendo uso del fprint y con
los parametros, pero me lio un poco con las dos funciones anteriores...
Pues eso. Gracias.
Primero de todo decir que estoy de acuerdo con los comentarios que te
han hecho sobre macros. Yo tampoco soy anti-macros pero no me gustan
por varias razones: tienen efectos laterales dificiles de preveer,
ocultan el tipo de los parametros, y ademas los depuradores no
entienden de macros. Ademas desde C99 tienes disponible las funciones
inline con lo que el uso de macros con la intencion de eficiencia
todavia tiene menos justificacion.

Por otra parte, el uso de macros es conveniente combinandola con
compilacion condicional, permitiendo adaptar facilmente el codigo a
distintos entornos de compilacion . Por ejemplo echa un vistazo a la
macro assert(), esta macro se comporta de forma totalmente distinta
segun tengas definido o no NDEBUG. Pero si te fijas, la implementacion
de assert es de lo mas sencilla, simplemente o bien llama a una
funcion, o no hace nada.

En cuanto a lo que hace la macro que muestras, parece que tiene varios
efectos:
- asigna a una variable el time actual
- construye una string especificada a traves de lo que parece seria
otra macro (lo cual me parece poco pensado)
- envia a un fichero una linea con la hora, tipo de hilo, hilo y la
string previamente formada.

Con esta definicion tienes varios problemas:
- No chequea en tiempo de compilacion los tipos de los parametros
que pasaras a fprintf (muy peligroso).
- Oculta el uso de la string temporal, con lo que pierdes
consciencia de como se usa y cual deberia ser su tamaño
- Tiene todos los problemas asociados a los efectos laterales en
evaluacion de macros

Podrias haberla definido de forma totalmente distinta:

#ifdef DEBUG_EVENT
void fprintEvent( FILE* file, const char* strHilo,
int hilo, time_t *reloj, const char* msg);

IMPR_EVENTO_HILO( fsalida, reloj, tipoHilo, \
hilo, msg) \
TIEMPO_EVENTO(reloj);\
fprintEvent( fsalida, tipoHilo, hilo, reloj, msg)

#else
IMPR_EVENTO_HILO( fsalida, reloj, tipoHilo, \
hilo, msg) \
TIEMPO_EVENTO(reloj)
endif

En particular aqui si esta definido DEBUG_EVENT se llama a una funcion
que chequea convenientemente los parametros. En cuanto a la macro
TIEMPO_EVENTO, si usas C99, podria ser una funcion inline.

De todas formas no me parece muy adecuado que una macro que se supone
loguea un mensaje, tenga el efecto lateral oculto de actualizar la
variable reloj con el time actual.

Un saludo,
Martin.

Loading...