実際の本体なしで関数マクロを定義すると、コンパイラーで空の文字列のようになりますか(つまり、コンパイル時に追加の命令が生成されません)?
例:
#define SomeMacro(a)
SomeMacro("hello"); // This line doesn't add any instructions, does it?
空のマクロはコードを生成しません。
これが役立つ2つの場所を見てきました。 1つは、関数パラメーターが使用されていない場合の警告を排除することです。
#define UNUSED(x)
int foo(int UNUSED(value))
{
return 42;
}
2つ目は、条件文を使用してコードがあるかどうかを判断する場合です。
#ifdef LOGGING_ENABLED
#define LOG(x) log_message(x)
#else
#define LOG(x)
#endif
あなたのコードは完全に正しくありません、私はあなたのマクロに空の括弧を置くことをお勧めします
#define somemacro(a) {}
その理由は簡単です、あなたのコードははるかに安全です!
この例を見てみましょう:
if(Value)
somemacro(a)
else
somemacro(b)
マクロが空の場合、コードはコンパイルされません! (「else」の前にプライマリ式が必要です)。とにかく、特定のスタイルルールでは、作成する必要があります
if(Value)
{
somemacro(a)
}
else
{
somemacro(a)
}
それは問題ではありません。
別のオプションは、「;」を使用することです。 "{}"の代わりに、同じオプションでそのオプションを指定すると、コンパイル時に警告が表示されますが、中括弧は警告もエラーも発生しません。 (セミコロンは警告を出してもなお良い);)
次のケースを取ります
if(value)
somemacro(a);
else
somemacro(b);
に拡大します
if(value)
{};
else
{};
コンパイルできません!
だからマクロは悪だ
(マクロは単純なテキスト置換であるため、ダムのルールは、常に手動でコードを置き換えて何が起こるかを確認することです。展開されたコードを表示するためにマクロを置き換えるツールもあります。)
完全に安全なマクロがあるかどうかを推測しますか?はい、「NOP」と呼ばれています
#define somemacro(a) ((void)0)
いずれの場合でも機能します(コンパイラのソースファイルでもそれをNOPとして使用します。たとえば、 "assert.h"だけを見てください。
プリプロセッサは、すべてのマクロでリテラル置換を実行します。
したがって、「空の」マクロを定義すると、コンパイラーが実行される前に、プリプロセッサーによって、コード内でそのIDが現れるそれぞれの場所が空のステートメントに置き換えられます。
あ、はい。質問の例ではコードは生成されません。
そのとおりです。あなたのコードは
;
前処理後。
コンパイラーにコードafter前処理(gccでは、これは-E
オプション;コンパイラは異なる場合があります)。