Are empty macro definitions allowed in C? How do they behave?

CC Preprocessor

C Problem Overview


Suppose the "empty" macro definition

#define FOO

Is it valid Standard C? If so, what is FOO after this definition?

C Solutions


Solution 1 - C

It is simply a macro that expands to, well, nothing. However, now that the macro has been defined you can check with #if defined (or #ifdef) whether it has been defined.

#define FOO

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

will expand to

int main(){

    printf("Hello world");
}

There are certain situations where this comes in very handy, for example additional debug information, which you don't want to show in your release 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");
    /* ... */
}

Since the macro CONFIG_USE_DEBUG_MESSAGES has been defined, DEBUG_MSG(x) will expand to print(x) and you will get Entering main. If you remove the #define, DEBUG_MSG(x) expands to an empty do-while loop and you won't see the message.

Solution 2 - C

Yes, empty define is allowed by the standard.

> C11 (n1570), § 6.10 Preprocessing directives
> 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)

A common utilisation is inclusion guards.

#ifndef F_H
# define F_H

#endif

Solution 3 - C

Empty macro definitions can also be used for self-documentation. The IN in the code snippet below is a sample. The code and the comment are both quoted from the EDK II project.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1150105View Question on Stackoverflow
Solution 1 - CZetaView Answer on Stackoverflow
Solution 2 - Cmd5View Answer on Stackoverflow
Solution 3 - CsmwikipediaView Answer on Stackoverflow