#define macro para la impresión de depuración en C?

3 minutos de lectura

avatar de usuario
jfarrell

Intentando crear una macro que se pueda usar para imprimir mensajes de depuración cuando se define DEBUG, como el siguiente pseudocódigo:

#define DEBUG 1
#define debug_print(args ...) if (DEBUG) fprintf(stderr, args)

¿Cómo se logra esto con una macro?

  • ¿El compilador (gcc) optimizará declaraciones como if(DEBUG) {…} out, si en el código de producción la macro DEBUG está establecida en 0? Entiendo que hay buenas razones para dejar las declaraciones de depuración visibles para el compilador, pero queda un mal presentimiento. -Palmadita

    – Pat

    2 de febrero de 2010 a las 10:48

  • Ver también Error al definir una macro de stringising con __VA_ARGS__

    – jww

    25 de febrero de 2019 a las 5:40


Entonces, cuando uso gcc, me gusta:

#define DBGI(expr) ({int g2rE3=expr; fprintf(stderr, "%s:%d:%s(): ""%s->%i\n", __FILE__,  __LINE__, __func__, #expr, g2rE3); g2rE3;})

Porque se puede insertar en el código.

Supongamos que está tratando de depurar

printf("%i\n", (1*2*3*4*5*6));

720

Entonces puedes cambiarlo a:

printf("%i\n", DBGI(1*2*3*4*5*6));

hello.c:86:main(): 1*2*3*4*5*6->720
720

Y puede obtener un análisis de qué expresión se evaluó a qué.

Está protegido contra el problema de la doble evaluación, pero la ausencia de gensyms lo deja abierto a colisiones de nombres.

Sin embargo anida:

DBGI(printf("%i\n", DBGI(1*2*3*4*5*6)));

hello.c:86:main(): 1*2*3*4*5*6->720
720
hello.c:86:main(): printf("%i\n", DBGI(1*2*3*4*5*6))->4

Así que creo que mientras evite usar g2rE3 como nombre de variable, estará bien.

Ciertamente lo he encontrado (y versiones aliadas para cadenas y versiones para niveles de depuración, etc.) invaluable.

  • Como para for(;0;)podría generar un problema cuando escribes algo como D continue; o D break;.

    – ACcreador

    10 sep 2014 a las 9:00

  • Me consiguió; sin embargo, parece muy poco probable que pueda ocurrir por accidente.

    – MBQ

    03/04/2015 a las 12:24

avatar de usuario
Janardhan B. Chinta

#define PRINT_LOG(str_format, ...) { \
    time_t curtime=time (NULL); \
    struct tm *ltm = localtime (&curtime); \
    printf("[%d-%02d-%02d %02d:%02d:%02d] " str_format, \
        ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, \
        ltm->tm_hour, ltm->tm_min, ltm->tm_sec, ##__VA_ARGS__); \
}
    
PRINT_LOG("[%d] Serving client, str=%s, number=%d\n", getpid(), "my str", 10);

  • Gracias por este fragmento de código, que podría proporcionar una ayuda limitada e inmediata. UN explicación apropiada mejoraría en gran medida su valor a largo plazo al mostrar por qué es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Edite su respuesta para agregar alguna explicación, incluidas las suposiciones que ha hecho.

    – Llamada al sistema

    20 de marzo de 2021 a las 15:46

avatar de usuario
jonathan leffler

De acuerdo a http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.htmldebe haber un ## antes de __VA_ARGS__.

De lo contrario, una macro #define dbg_print(format, ...) printf(format, __VA_ARGS__) no compilará el siguiente ejemplo: dbg_print("hello world");.

  • Gracias por este fragmento de código, que podría proporcionar una ayuda limitada e inmediata. UN explicación adecuada mejoraría en gran medida su valor a largo plazo al mostrar por qué es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Edite su respuesta para agregar alguna explicación, incluidas las suposiciones que ha hecho.

    – Llamada al sistema

    20 de marzo de 2021 a las 15:46

avatar de usuario
5tenzel

Esto es lo que uso:

#if DBG
#include <stdio.h>
#define DBGPRINT printf
#else
#define DBGPRINT(...) /**/  
#endif

Tiene el gran beneficio de manejar printf correctamente, incluso sin argumentos adicionales. En caso de que DBG ==0, incluso el compilador más tonto no tiene nada que analizar, por lo que no se genera código.

  • Es mejor que el compilador siempre verifique el código de depuración.

    –Jonathan Leffler

    8 de febrero de 2015 a las 5:41

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad