2013-04-26 19 views
41

Es ist mir bei der Verwendung von Compiler-Direktiven unklar, welche der folgenden zwei Codeschnipsel richtig/bevorzugt sind und warum. Es scheint, dass die meisten Entwickler und Open-Source-Projekte, die ich gesehen habe, die erste verwenden, aber ich habe die zweite auch häufig benutzt gesehen.#ifdef DEBUG versus #if DEBUG

#ifdef DEBUG 
[self doSomethingOnlyWhenDebugging]; 
#endif 

VERSUS

#if DEBUG 
[self doSomethingOnlyWhenDebugging]; 
#endif 

Welche der oben genannten Code-Schnipsel vorzuziehen ist für die Ausführung von Code nur beim Debuggen und warum? Meine Vermutung ist, dass die erste ausgeführt wird, wenn DEBUG als TRUE oder FALSE definiert ist, wobei die zweite nur ausgeführt wird, wenn DEBUG definiert und auf TRUE gesetzt ist. Ist das korrekt?

+9

'# ifdef' testet einfach, ob das Symbol definiert wurde.'# if' testet den Wert des Symbols. "#define FOO 0" wird also "#ifdef FOO" wahr machen, aber "#if FOO" ist falsch, weil es '#if 0' ist. –

+0

Sie sollten versuchen, die "root" -Definition zu finden und zu bestimmen, ob der Wert ein 1/0-Wert oder ein vorhanden/abwesend sein soll. Sie falsch zu verstehen, kann "unerwartete" Konsequenzen haben. –

Antwort

35

Sie haben Recht. #if DEBUG wird nicht ausgewertet, wenn DEBUG als 0 definiert ist.

Was, wenn jeder verwenden, können Sie kleben #ifdef für etwas verwenden, wo man nur zu benötigen Code hinzufügen, wenn die Präprozessordefinition vorhanden ist, wie die Debug-Protokollierung hinzugefügt wird. Wenn Sie den Wert überprüfen und verschiedene Kompilierpfade durchlaufen müssen, würde ich einen 0 oder 1 verwenden. Ein gutes Beispiel dafür ist TARGET_IPHONE_SIMULATOR, das immer für ein iOS-Projekt definiert ist, aber nur 1, wenn Sie für den Simulator kompilieren.

+1

Wenn ich also eine Codezeile nur im Simulator ausführen wollte, müsste ich '# if' verwenden, weil' TARGET_IPHONE_SIMULATOR' definiert ist, egal ob ich mit dem Simulator arbeite oder nicht. Richtig? – lidsinker

+2

@lidsinker richtig – Kevin

+0

gut erklärt. Ich danke dir sehr –

6

Wie ich weiß, die beste Wahl ist:

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

dann werden Sie wissen #ifndef DEBUG vor allen anderen bevorzugt. Es ist eine einfachere Wahl:

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

Wenn jedoch -Wundef Compiler-Flag eingeschaltet ist, könnte es ein seine Warnung mit #if DEBUG == 0.

1

Sie müssen den Code suchen, in dem DEBUG definiert oder nicht definiert ist, und schreiben Sie Ihren Code entsprechend. Mit DEBUG werden Sie feststellen, dass es entweder nicht definiert ist, oder mit einem Wert von 1 definiert. Also entweder #if DEBUG oder #ifdef DEBUG wird funktionieren.

Für #define, die unter Ihrer Kontrolle sind, empfehle ich, dass Sie sie immer definieren, entweder mit einem Wert von 0 oder 1. Sie können dann #if verwenden, um den Wert zu überprüfen, aber Sie können sie auch direkt in verwenden eine gewöhnliche if-Anweisung oder in einem Ausdruck, die Ihren Code lesbarer macht. Und da es immer definiert ist, können Sie "Gehe zu Definition" in Xcode verwenden, um zu dem Ort zu gelangen, an dem es definiert wurde, und überprüfen, wie und warum es festgelegt ist. Wenn Sie stattdessen entweder #define oder nicht #define den Wert, und es ist nicht definiert, dann wird Xcode keine Ahnung haben, wo in Ihrem Quellcode nicht definiert ist. Es gibt Ihnen auch die Möglichkeit, nach falsch geschriebenen Verwendungen zu suchen. Wenn "Zur Definition springen" nicht funktioniert, wissen Sie, dass Sie falsch geschrieben haben. Innerhalb einer #if Direktive wird jedes Makro, das nicht definiert ist, durch 0 ersetzt. Also #if DEBUG funktioniert, wenn DEBUG nicht definiert ist, oder wenn DEBUG als 0 definiert ist, und es wird nicht kompiliert, wenn DEBUG als definiert ist nichts - was dir sagen wird, was falsch ist, damit du es reparieren kannst. Von diesem Standpunkt aus ist die Verwendung von #if besser, es sei denn, es kompiliert nicht.