Necesito imprimir msg1 y msg2 para el mismo error cuando se compila con y sin el indicador DEBUG. P.ej.

      fprintf( stderr,
#ifdef DEBUG
                      "error msg1 %s",__FILE__
#else
                      "error msg2"
#endif
              );

U otra forma podría ser pasar estos msg1 y msg2 a una función e imprimirla usando vfprintf(). Probablemente, el segundo método habría ejecutado el tiempo de sobrecarga. Entonces, me pregunto qué podría ser una mejor manera de hacer esto.

P.ej. Un caso de uso podría ser que el código debe compilarse con las banderas info y debug. info pueden ser mensajes relacionados con el usuario y debug para fines de depuración. ¿Alguna sugerencia?

1
Shivendra Mishra 25 dic. 2016 a las 19:54

3 respuestas

La mejor respuesta

Usualmente, las trazas se usan en el código para ayudar a depurarlo, por lo que, por ejemplo, en las pruebas de puntero NULL puede agregar algo como if (ptr==NULL) DEBUG("Entering Null pointer");. Solo te digo eso porque no entiendo por qué quieres usar tanto msg1 como msg2.

Para mí, generalmente uso una macro DEBUG y una variable global verbose:

#define DEBUG(...)\
if(verbose && SHOW_ERROR) {\
printf("Error : %s, %d",__FUNCTION__, __LINE__);\
printf(__VA_ARGS__);\
}\
else if (verbose && SHOW_WARNING) {\
printf("Warning : %s, %d",__FUNCTION__, __LINE__);\
printf(__VA_ARGS__);\
}

Ejemplo:

#include <stdio.h>

#define SHOW_ERROR 1
#define SHOW_WARNING 2

int verbose = 1; 
int main()
{
  DEBUG("THIS WILL SHOW ERROR MSG");
  verbose = 2;
  DEBUG("THIS WILL SHOW WARNING MSG");
}

Espero ayudar.

2
Mouin 25 dic. 2016 a las 17:58

Su indicador de depuración es una macro de preprocesador, por lo que el mensaje de error se elegirá en el momento de la compilación, ¿es este el comportamiento que desea?

Sugeriría un enfoque ligeramente diferente:

#define PRINT_INFO(msg1,msg2) if(dbg){fprintf(stderr,msg1);}\
                              else{fprintf(stderr,msg2);}

Donde el indicador dbg se puede activar y desactivar en tiempo de ejecución

Puedes jugar aún más usando macros variadic:

#define PRINT_INFO_VAR(msg1,msg2...) if(dbg){fprintf(stderr,msg1);}\
                                     else{fprintf(stderr,msg2);}

Y para el ejemplo que le diste se vería así:

PRINT_INFO_VAR(msg1,msg2,a)
1
Nimrod Morag 25 dic. 2016 a las 17:12

Una llamada incondicional a vfprintf conlleva una sobrecarga adicional para empaquetar el parámetro adicional, a, para usar con la función de lista de argumentos variables. Además, la compilación condicional le permite al compilador notar que la llamada a fprintf en modo DEBUG no pasa parámetros distintos a la cadena de formato, y la reemplaza con fputs("error msg1", stderr) *

Sin embargo, esta sobrecarga es pequeña, y es poco probable que note nada de esto, porque la escritura ocurre incondicionalmente y va a dominar el momento de la llamada.

* Es raro que la salida DEBUG proporcione menos detalles que el que no es de depuración; por lo general, es al revés.

1
dasblinkenlight 25 dic. 2016 a las 17:01