Supponiamo che la definizione di macro “vuota”
#define FOO
È valido lo standard C? In caso affermativo, che cos’è FOO
dopo questa definizione?
È semplicemente una macro che si espande, beh, nulla. Tuttavia, ora che la macro è stata definita, è ansible verificare con #if defined
(o #ifdef
) se è stato definito.
#define FOO int main(){ FOO FOO FOO printf("Hello world"); }
si espanderà a
int main(){ printf("Hello world"); }
Ci sono alcune situazioni in cui questo è molto utile, ad esempio ulteriori informazioni di debug, che non vuoi mostrare nella versione di rilascio:
/* 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"); /* ... */ }
Poiché la macro CONFIG_USE_DEBUG_MESSAGES
è stata definita, DEBUG_MSG(x)
si espanderà per print(x)
e otterrai Entering main
. Se rimuovi #define
, DEBUG_MSG(x)
espande in un ciclo do
– while
vuoto e non vedrai il messaggio.
Sì, la definizione vuota è consentita dallo standard.
C11 (n1570), § 6.10 Direttive di preelaborazione
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)
Un utilizzo comune sono le guardie di inclusione.
#ifndef F_H # define F_H #endif
Le definizioni di macro vuote possono anche essere utilizzate per l’auto-documentazione. L’ IN
nello snippet di codice seguente è un esempio. Il codice e il commento sono entrambi citati dal progetto EDK II .
// // 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 );