Le definizioni di macro vuote sono consentite in C? Come si comportano?

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 dowhile 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 );