2013-04-26 28 views
41

Non è chiaro per me quando si utilizzano le direttive del compilatore quali dei seguenti due frammenti di codice sono corrette/preferite e perché. Sembra che la maggior parte degli sviluppatori e dei progetti Open Source che ho visto utilizzino la prima, ma ho visto anche la seconda usata frequentemente.#ifdef DEBUG versus #if DEBUG

#ifdef DEBUG 
[self doSomethingOnlyWhenDebugging]; 
#endif 

VERSUS

#if DEBUG 
[self doSomethingOnlyWhenDebugging]; 
#endif 

Quale dei frammenti di codice di cui sopra è preferibile per l'esecuzione di codice solo durante il debug e perché? La mia ipotesi è che il primo verrà eseguito se DEBUG è definito come VERO o FALSO in cui il secondo verrà eseguito solo se DEBUG è definito e impostato su TRUE. È corretto?

+9

'# ifdef' semplicemente verifica se il simbolo è stato definito.'# se' verifica il VALORE del simbolo. quindi '#define FOO 0' farà sì che' #ifdef FOO' sia vero, ma '#if FOO' è falso, perché sta facendo' #if 0'. –

+0

Si dovrebbe tentare di trovare la definizione "radice" e determinare se il valore deve essere un valore 1/0 o uno presente/assente. Il fatto di sbagliare può avere conseguenze "inaspettate". –

risposta

35

Sei corretto. #if DEBUG non valuterà se DEBUG è definito come 0.

Per quanto riguarda quando utilizzare ciascuna, si può attaccare ad usare #ifdef per tutto ciò in cui hai solo bisogno di aggiungere codice, se la definizione del preprocessore è presente, come ad esempio l'aggiunta di registrazione di debug. Se è necessario ispezionare il valore e scendere in percorsi di compilazione diversi, utilizzare uno 0 o 1. Un buon esempio di questo è TARGET_IPHONE_SIMULATOR, che è sempre definito per un progetto iOS, ma solo 1 se stai compilando per il simulatore.

+1

Quindi, se volessi eseguire qualche riga di codice solo nel simulatore, avrei bisogno di usare "# if" perché "TARGET_IPHONE_SIMULATOR" è definito indipendentemente dal fatto che sia in esecuzione su Simulator o meno. Corretta? – lidsinker

+2

@lidsinker corretto – Kevin

+0

ben spiegato. Grazie mille –

6

Per quanto ne so, la scelta migliore è:

#ifndef DEBUG 
    NSLog(@"-1"); 
#elif DEBUG == 0 
    NSLog(@"0"); 
#else 
    NSLog(@"%d", DEBUG); 
#endif 

poi, si sa #ifndef DEBUG è preferito sopra tutti gli altri. V'è una scelta semplice:

#if DEBUG == 0 // DEBUG is not defined or defined to be 0 
    // do sth 
#else 
    // do sth 
#endif 

Tuttavia, se -Wundef compilatore bandiera è su, ci potrebbe essere un avvertimento con #if DEBUG == 0.

1

È necessario esaminare il codice in cui DEBUG viene definito o non definito e scrivere il codice di conseguenza. Con DEBUG, scoprirai che non è definito né definito con un valore di 1. Quindi, il DEBUG #if DEBUG o lo #ifdef DEBUG funzionerà.

Per #define 's che sono sotto il vostro controllo, vi consiglio che li si definisce sempre, sia con un valore pari a 0 o 1. È quindi possibile utilizzare #if per verificare il valore, ma è anche possibile utilizzarli direttamente in un'istruzione if ordinaria o un'espressione, che può rendere più leggibile il tuo codice. E poiché è sempre definito, puoi usare "Jump To Definition" in Xcode per andare al punto in cui è definito e verificare come e perché è impostato. Se invece è il valore #define o non #define e non è definito, Xcode non avrà idea di dove nel codice sorgente non sia definito. Ti dà anche la possibilità di cercare usi errati. Se "Jump to Definition" non funziona, allora sai di averlo sbagliato.

BTW All'interno di una direttiva #if, qualsiasi macro non definita viene sostituita da 0. Quindi DEBUG #if funzionerà se DEBUG non è definito, o se DEBUG è definito come 0 e non verrà compilato se DEBUG è definito come niente - che ti dirà cosa c'è che non va, così puoi sistemarlo. Da questo punto di vista, l'utilizzo di #if è migliore a meno che non venga compilato.