2012-12-15 7 views

Antwort

38

Es ist einfach ein Makro, das erweitert wird, naja, nichts. Nachdem das Makro jedoch definiert wurde, können Sie mit #if defined (oder #ifdef) überprüfen, ob es definiert wurde.

#define FOO 

int main(){ 
    FOO FOO FOO 
    printf("Hello world"); 
} 

expandieren zu

int main(){ 

    printf("Hello world"); 
} 

gibt es bestimmte Situationen, in denen dies in sehr praktisch ist, zum Beispiel zusätzliche Debug-Informationen, die Sie nicht wollen, in Ihrem Release-Version zeigen:

/* Defined only during debug compilations: */ 
#define CONFIG_USE_DEBUG_MESSAGES 

#ifdef CONFIG_USE_DEBUG_MESSAGES 
#define DEBUG_MSG(x) print(x) 
#else 
#define DEBUG_MSG(x) do {} while(0) 
#endif 

int main(){ 
    DEBUG_MSG("Entering main"); 
    /* ... */ 
} 

Da das Makro CONFIG_USE_DEBUG_MESSAGES definiert wurde, wird DEBUG_MSG(x) auf print(x) erweitert und Sie erhalten Entering main. Wenn Sie die #define entfernen, wird DEBUG_MSG(x) zu einer leeren do - while Schleife erweitert und Sie werden die Nachricht nicht sehen.

+1

Dies ist sehr riskant, da es Kompilierung vor allem brechen kann. wenn Sie Anweisungen wie '' 'haben, wenn (x) DEBUG_MSG (" test "); sonst DEBUG_MSG ("test"); '' '. Ich bevorzuge es, mein leeres Makro mit einer no-effect-Anweisung zu deklarieren wie '' '#define DEBUG_MSG (x) do {} while (0)' '' – Ely

+0

@Ely ein besseres Beispiel ist ein Header-Guard. Wie auch immer, behoben. – Zeta

15

Ja, leere Definition ist vom Standard erlaubt.

C11 (n1570), § 6.10 vorverarbeiten Richtlinien

control-line: 
    # define identifier replacement-list new-line 
    # define identifier lparen identifier-list(opt)) replacement-list new-line 
    # define identifier lparen ...) replacement-list new-line 
    # define identifier lparen identifier-list , ...) replacement-list new-line 
replacement-list: 
    pp-tokens(opt) 

Eine gemeinsame Nutzung ist Wachen Inklusion.

+0

Sie haben nicht geantwortet, was der Wert von 'FOO' nach der leeren Definition ist. –

+3

@ user14284 Makros haben keine Werte. Sie erweitern zu einer Liste von Token. Diese Liste kann leer sein. – melpomene

1

Leere Makrodefinitionen können auch für die Selbstdokumentation verwendet werden. Die IN im Code-Snippet unten ist ein Beispiel. Der Code und der Kommentar werden beide aus der EDK II project zitiert.

// 
// Modifiers for Data Types used to self document code. 
// This concept is borrowed for UEFI specification. 
// 

/// 
/// Datum is passed to the function. 
/// 
#define IN 


typedef 
EFI_STATUS 
(EFIAPI *EFI_BLOCK_RESET)(
    IN EFI_BLOCK_IO_PROTOCOL   *This, 
    IN BOOLEAN      ExtendedVerification 
); 
+0

Ich würde ein anderes Beispiel verwenden. Es muss kein Zitat aus dem tatsächlichen Code sein, aber das aktuelle Beispiel enthält eine ziemlich große Menge unnötiger Informationen. (Übrigens, stellen Sie sicher, dass Ihre Antwort immer noch die ursprüngliche Frage beantwortet; es funktioniert gut mit den anderen Antworten, aber als eigenständige Antwort passt es nicht wirklich zur Frage "Was erweitert' FOO'? "). – Zeta

+0

Danke, dass Sie darauf hingewiesen haben. Ich lese zufällig gerade diesen Code, wenn ich diese Frage sehe. Da die Antwort lange gewählt wurde, hoffe ich nur, dass meine Antwort als eine pädagogische Referenz dienen kann. – smwikipedia

Verwandte Themen