質問
#ifndef MACROS_NULLCHECK_H_
#define MACROS_NULLCHECK_H_
#include <assert.h>
#define NULLCHECK(x) assert(x != (void *) 0);
#endif
マクロを宣言するためのテンプレートとして上記のスタイルを使用した場合、どのような条件がありますか?
解決
-
引数を括弧で囲みます(式を渡すときに問題を防ぎます)
-
入れないでください。最後に(使用はより自然になります)
#define NULLCHECK(x)assert((x)!=(void *)0)
他のヒント
一般的に言えば、マクロの引数は常に展開の括弧内に入れてください。つまり、あなたの場合です
assert((x) != (void*) 0)
これは、渡さない式(単純な変数ではなく)が変数展開を台無しにする可能性があるためです。
また、マクロ定義の最後にセミコロンを置かないことをお勧めします。したがって、次のように呼び出す必要があります
NULLCHECK(pSomething);
これは、Cのような&amp;残りのコードと一貫性があります。
変更する可能性のある変更の1つは、終了 #endif
にコメントすることです。
#endif // MACROS_NULLCHECK_H_
ファイルが画面より長くなったときに、 #endif
がそこで何をしているのかを理解しやすくします。
CERT Cの優れたマクロプラクティスセキュアコーディングWiki :
PRE00-C。関数のようなマクロよりもインライン関数または静的関数を優先する
PRE01-Cマクロ内でパラメーター名を囲む括弧を使用する
PRE02-Cマクロ置換リストは括弧で囲む必要があります
PRE03-Cエンコードタイプの定義にtypedefを優先する
PRE10-C。 do-whileループで複数ステートメントマクロをラップする
PRE11-C。セミコロンで単一のステートメントマクロ定義を終了しない
PRE31-C。割り当て、インクリメント、デクリメント、揮発性アクセス、または関数呼び出しを含む引数で安全でないマクロを呼び出さないでください
PRE32-C。マクロ引数内でプリプロセッサディレクティブを使用しないでください
よさそうだ。よく使うパターンです。
;
を強制するには、
#define NULLCHECK(x) do { assert((X)); } while (0)