2009-06-12 14 views
22

estoy tratando de tener un modo de depuración en lo que si#define DEBUG 1

#define DEBUG 1 

Quiero printf algunos valores de las variables y si

#define DEBUG 0 

los quiero fuera.

El problema es que tengo muchos archivos de implementación y quiero que esta variable DEBUG esté disponible para todo el proyecto. Ahora mismo necesito editar la variable DEBUG en foo1.c, foo2.c, foo3.c que parece tedioso y propenso a errores y debe haber una mejor manera. ¿Alguna sugerencia?

Respuesta

70

Al compilar, debe poder especificar una opción para su compilador. Por ejemplo, puede llamar a GCC con la opción -DDEBUG.

En este caso, sería mejor usando:

#ifdef DEBUG 
#endif 

o:

#if defined(DEBUG) 
#endif 

si esta no es la forma en que está haciendo ahora. Me sorprende que no tenga un archivo de encabezado global para su proyecto. Algo similar a:

#ifdef DEBUG 
#undef DEBUG 
#endif 
#define DEBUG 1 

en un archivo llamado "debug.h". En sus programas C, puede incluir esto usando #include "debug.h"

+1

+1. Esta es la mejor manera de hacerlo. – Brian

+4

¿No es 'gcc -DDEBUG' en lugar de' -dDEBUG'? –

+0

@ Alan: ¡Buen punto! –

4

Coloque el "#define DEBUG" en "debug.h" y #incluya ese archivo de encabezado en cada archivo * .c.

+1

Puede que no sea el camino correcto a seguir. Use el archivo Makefile para administrar el modo de compilación, DEPURACIÓN o LIBERACIÓN. Por lo tanto, de acuerdo con el modo de compilación, varía lo que entra en CFLAGS. Ese enfoque escalará sin problemas. –

1

Pruebe esto en su lugar.

En el primer archivo que tiene y que se incluirán:

#define DEBUG 

Entonces cada vez que desea tener código de depuración, haga lo siguiente:

#ifdef DEBUG 
do some stuff 
#endif 

Esto también evitará que su código de depuración de hacer en el código de lanzamiento.

+0

No creo que haya entendido su pregunta. –

4

Como dice @ person-b, especifique esta definición como una opción del compilador, p. Ej. -D DEBUG

Nota sin embargo que para simplificar esto debe cambiar la prueba en el código de:

#if DEBUG 

a:

#ifdef DEBUG 

De esta manera usted no tiene que preocuparse acerca de la especificación un valor de 0 o 1, pero puede confiar en que se lo defina o no.

2

La sugerencia de samoz y Stephen Doyle para verificar la existencia de una definición para DEBUG en lugar de su valor es buena. Sin embargo, si realmente desea utilizar DEBUG = 0, así es como puede hacerlo: cada vez que defina el indicador DEBUG (es decir, En cada archivo), compruebe si hay una definición existente:

#ifndef DEBUG 
#define DEBUG 1 
#endif 

Entonces, cuando se utiliza la opción -DDEBUG = 0 con su compilador, no se ejecutará la línea #define.

+0

Invertiría el valor predeterminado: DEBUG 0 normalmente, pero anulado en la línea de comando. –

13

intentar algo como Steve McConnell sugiere en la sección 6 del "Capítulo 8: Programación defensiva" de Code Complete 2 ... Añadir esto a su código:

#ifdef DEBUG 
#if (DEBUG > 0) && (DEBUG < 2) 
printf("Debugging level 1"); 
#endif 

#if (DEBUG > 1) && (DEBUG < 3) 
printf("Debugging level 2"); 
#endif 

#if (DEBUG > n-1) && (DEBUG < n) 
printf("Debugging level n"); 
#endif 
#endif 

Luego, cuando se compila, anadir este indicador (aviso: esto podría ser dependiente del compilador):

-DDEBUG=m 

O tener un encabezado global que define este tipo de cosas, como han sugerido otros.

+0

buena sugestión, pero ¿cuál es el nombre del libro? – simonppg

+0

@simonppg: Se agregó un enlace para [Code Complete, 2nd edition] (http://cc2e.com/). – Pete

0

personalmente me gusta

 
#ifdef DEBUG 
#define IFDEBUG if(0)else 
#else 
#define IFDEBUG if(1)else 
#endif 
+0

excelente como metodología de ofuscación ... – jpinto3912

5

Como una respuesta a su problema también se puede simplemente invocar el compilador como:

cc -c -DDEBUG=1 

o

cc -c -DDEBUG=0 

debe eliminar el "definen DEBUG 1/0 "en sus archivos - o reemplácelo por:

#ifndef DEBUG 
#define DEBUG 0 
#endif 

Aquí es lo que estoy utilizando (sintaxis GCC):

  • crear un Debug.h archivo con el siguiente contenido e incluirlo en cada archivo c:

    #ifdef DEBUG 
    extern FILE *dbgf; 
    #define D_MIN 0x00010000 // Minimum level 
    #define D_MED 0x00020000 // Medium level 
    #define D_MAX 0x00040000 // Maximum level 
    #define D_FLUSH 0x00080000 // Usefull by a program crash 
    #define D_TRACE 0x00100000 
    #define D_1  0x00000001 
    ... 
    
    #define D(msk, fmt, args...) if(msk & dbgmsk) { fprintf(dbgf, "%s:",__FUNCTION__); fprintf(dbgf, fmt, ## args); if(msk & D_FLUSH) fflush(dbgf); } 
    #define P(msk, fmt, args...) if(msk & dbgmsk) { fprintf(dbgf, fmt, ## args); if(msk & D_FLUSH) fflush(dbgf); } 
    
    #else 
    #define D(msk, fmt, args...) 
    #define P(msk, fmt, args...) 
    #endif 
    

dbgmsk es variable, que puede ser global (todo el programa) o local/estática y debe inicializarse un inicio. Puede definir varias opciones para todo el programa o para cada módulo. Esto es mejor y más flexible que la versión con la variable de nivel.

Ej. module1.c:

#include "debug.h" 

static int dbgmsk; // using local dbgmsk 
module1_setdbg(int msk) { dbgmsk = msk; D(D_TRACE,"dbgmsk1=%x\n", dbgmsk); } 

foo1() { P(D_1, "foo1 function\n"); 
    .... 
} 
foo2() {} 
... 

foo3.c

#include "debug.h" 
extern int dbgmsk; // using global dbgmsk 

Ex. principal:

#include "debug.h" 
FILE *dbgf; 
int dbgmsk = 0; // this is the global dbgmsk 

int main() { 
    dbgf = stderr; // or your logfile 
    dbgmsk = D_MIN; 
    module1_setdbg(D_MIN|D_MED|D_TRACE|D_1); 
    .... 
} 

También estoy almacenar todas las variables dbgmsk en un archivo de texto de configuración que se lee al inicio del programa.

+0

Es mejor asegurarse de que el compilador siempre vea, pero no siempre actúe sobre, la impresión de diagnóstico. La cláusula #else debería hacer algo como: #define D (msk, fmt, ...) do {if (0 && (msk & dbgmsk)) printf (fmt, __VARARGS__); } while (0). La expresión do/while asegura que puede usar esto en cualquier lugar donde pueda aparecer una declaración; if (0) significa que el código nunca se ejecuta, y el compilador lo optimizará, pero solo después de verificar su validez sintáctica. Si define la versión sin depuración en nada, no obtiene una verificación continua de que el código de depuración sea sintácticamente válido. –

+0

Tienes razón. ¡Tx! – bill