It is simply a macro that expands to, well, nothing.
A macro is a piece of code in a program that is replaced by the value of the macro. Macro is defined by #define directive. Whenever a macro name is encountered by the compiler, it replaces the name with the definition of the macro. Macro definitions need not be terminated by a semi-colon(;).
Inside of a C source file, you can use the #ifdef macro to check if a macro is defined.
A macro is a fragment of code that is given a name. You can define a macro in C using the #define preprocessor directive. Here's an example. Here, when we use c in our program, it is replaced with 299792458 .
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.
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
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
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With