「空の」マクロ定義を仮定します
#define FOO
それは有効な標準 C ですか? もしそうなら、FOO
この定義の後には何がありますか?
それは単に展開して何にもならないマクロです。ただし、マクロが定義されたので、 #if defined
(または#ifdef
) でマクロが定義されているかどうかを確認できます。
#define FOO
int main(){
FOO FOO FOO
printf("Hello world");
}
に拡大します
int main(){
printf("Hello world");
}
リリース バージョンに表示したくない追加のデバッグ情報など、これが非常に役立つ特定の状況があります。
/* 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");
/* ... */
}
マクロCONFIG_USE_DEBUG_MESSAGES
が定義されているため、DEBUG_MSG(x)
に展開され、print(x)
が得られEntering main
ます。を削除すると、空のループに展開され、#define
メッセージは表示されません。DEBUG_MSG(x)
do
while
はい、空の定義は標準で許可されています。
C11 (n1570)、§ 6.10 前処理指令
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)
一般的な使用法は、包含ガードです。
#ifndef F_H
# define F_H
#endif
空のマクロ定義は、自己文書化にも使用できます。以下のIN
コード スニペットはサンプルです。コードとコメントはどちらも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
);