Les définitions de macro vides sont-elles autorisées en C? Comment se comportent-ils?

Supposons la définition de la macro “vide”

#define FOO 

Est-ce la norme C valide? Si oui, qu’est-ce que FOO après cette définition?

Il s’agit simplement d’une macro qui ne prend plus rien. Cependant, maintenant que la macro a été définie, vous pouvez vérifier avec #if defined #ifdef (ou #ifdef ) si elle a été définie.

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

va s’étendre à

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

Dans certaines situations, cela s’avère très utile, par exemple des informations de débogage supplémentaires, que vous ne souhaitez pas afficher dans votre version:

 /* 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"); /* ... */ } 

Comme la macro CONFIG_USE_DEBUG_MESSAGES a été définie, DEBUG_MSG(x) sera étendu à print(x) et vous obtiendrez Entering main . Si vous supprimez le #define , DEBUG_MSG(x) développe en une boucle vide – while et vous ne verrez pas le message.

Oui, définir vide est autorisé par la norme.

C11 (n1570), § 6.10 Directives de prétraitement

 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) 

Les gardes d’inclusion sont une utilisation courante.

 #ifndef F_H # define F_H #endif 

Les définitions de macros vides peuvent également être utilisées pour l’auto-documentation. L’ IN dans l’extrait de code ci-dessous est un exemple. Le code et le commentaire sont tous deux cités dans le projet 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 );