2009-06-12 13 views
22

Sto cercando di avere una modalità di debug su così se#define DEBUG 1

#define DEBUG 1 

voglio printf alcuni valori delle variabili e se

#define DEBUG 0 

li voglio fuori.

Il problema è che ho molti file di implementazione e voglio che questa variabile DEBUG sia disponibile per l'intero progetto. In questo momento ho bisogno di modificare la variabile DEBUG in foo1.c, foo2.c, foo3.c che sembra noioso e soggetto ad errori e ci deve essere un modo migliore. Eventuali suggerimenti?

risposta

70

Durante la compilazione, dovresti essere in grado di specificare un'opzione per il compilatore. Ad esempio, è possibile chiamare GCC con l'opzione -DDEBUG.

In questo caso, sarebbe meglio utilizzare:

#ifdef DEBUG 
#endif 

o:

#if defined(DEBUG) 
#endif 

se questo non è il modo in cui si sta facendo ora. Sono sorpreso che tu non abbia un file di intestazione globale per il tuo progetto. Qualcosa sulla falsariga di:

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

in un file chiamato "debug.h". Nei tuoi programmi C, puoi includerlo utilizzando #include "debug.h"

+1

+1. Questo è il modo migliore per farlo. – Brian

+4

Non è 'gcc -DDEBUG' invece di' -dDEBUG'? –

+0

@Alan: buon punto! –

4

Inserisci "#define DEBUG" in "debug.h" e # include il file di intestazione in ogni file * .c.

+1

Potrebbe non essere la strada giusta da percorrere. Usa il Makefile per gestire la modalità build, DEBUG o RELEASE. Quindi, in base alla modalità di compilazione, varia ciò che entra nei CFLAG. Questo approccio si ridimensionerà perfettamente. –

1

Prova questo.

Nel primo file che avete che sarà incluso:

#define DEBUG 

Poi ogni volta che si desidera avere il codice di debug, fare questo:

#ifdef DEBUG 
do some stuff 
#endif 

questo sarà anche evitare che il codice di debug da fare nel codice di rilascio.

+0

Non penso che tu abbia capito la sua domanda. –

4

Come @ person-b dice, specifica questa definizione come opzione del compilatore, ad es. -D DEBUG

Nota però che per semplificare questo si dovrebbe cambiare il test nel codice da:

#if DEBUG 

a:

#ifdef DEBUG 

In questo modo non c'è bisogno di preoccuparsi di specificare un valore 0 o 1, ma può invece fare affidamento sulla sua definizione o meno.

2

Il suggerimento di samoz e Stephen Doyle per verificare l'esistenza di una definizione per DEBUG piuttosto che il suo valore è buono. Tuttavia, se vuoi veramente usare DEBUG = 0, questo è il modo in cui puoi farlo: Ogni volta che definisci il flag DEBUG (ad es., In ogni file), verificare la presenza di una definizione esistente:

#ifndef DEBUG 
#define DEBUG 1 
#endif 

Poi, quando si utilizza l'opzione -DDEBUG = 0 con il compilatore, non verrà mai eseguita la linea #define.

+0

Vorrei invertire l'impostazione predefinita: DEBUG 0 normalmente, ma sovrascrivibile sulla riga di comando. –

13

provare qualcosa di simile Steve McConnel suggerisce nella sezione 6 di "Capitolo 8: Mediano di programmazione" dal Code Complete 2 ... Aggiungi questo al vostro codice:

#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 

Poi, quando si compila, aggiungere questo flag (attenzione: Questo potrebbe essere compilatore-dipendente):

-DDEBUG=m 

Oppure, avere un'intestazione globale che definisce questo genere di cose, come altri hanno suggerito.

+0

simpatia, ma qual è il nome del libro? – simonppg

+0

@simonppg: collegamento aggiunto per [Code Complete, 2nd edition] (http://cc2e.com/). – Pete

0

mi piace personalmente

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

grande come metodologia di offuscamento ... – jpinto3912

5

Come risposta al vostro problema si può anche semplicemente richiamare il compilatore come:

cc -c -DDEBUG=1 

o

cc -c -DDEBUG=0 

È necessario eliminare il "define DEBUG 1/0 "nei tuoi file - o sostituirlo con:

#ifndef DEBUG 
#define DEBUG 0 
#endif 

Ecco quello che sto usando (sintassi GCC):

  • creare un Debug.h file con il seguente contenuto e includerlo in ogni file 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 è variabile, che può essere globale (intero programma) o locale/statico e deve essere inizializzato un avvio. È possibile definire diverse opzioni per l'intero programma o per ciascun modulo. Questo è migliore e più flessibile della versione con la variabile di livello.

Es. 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 

Es. main:

#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); 
    .... 
} 

Sto anche memorizzando tutte le variabili dbgmsk in un file di testo di configurazione che viene letto all'avvio del programma.

+0

E 'meglio per assicurare che il compilatore vede sempre, ma non sempre agire su, la stampa diagnostica. La clausola #else dovrebbe fare qualcosa di simile: # define D (MSK, fmt, ...) do {if (0 && (MSK & dbgmsk)) printf (fmt, __VARARGS__); } while (0). L'idioma do/while assicura che puoi usarlo ovunque possa apparire una dichiarazione; if (0) significa che il codice non viene mai eseguito e il compilatore lo ottimizzerà, ma solo dopo averlo verificato per la validità sintattica. Se si definisce la versione non debug su nulla, non si ottiene il controllo continuo del fatto che il codice di debug sia sintatticamente valido. –

+0

Hai ragione. Tx! – bill