teppyinline関数やconst変数を使ってもC言語時代に#defineマクロによって実現していたことの全てをカバーできるわけではありません。Processor)の力は偉大です。ビルドレベルに応じて違う挙動になるような処理を実現するには#defineによるマクロは有効な選択です。while(0)#endif以下のように使います。0;}DEBUG_LOGの定義を見て下さい。マクロで展開したい実際の処理(std::printf)をdo{...}while(0)で囲んでます。これはどういう意図でしょうか。do{...}while(0)としたところで、内部のステートメントは1度しか実行されません。((!exp)){std::printf(__VA_ARGS__)}と書くのと処理的には何も変わらないように見えます。実際には後者の定義は行末の;(セミコロン)を強制できない記述する場所によっては意図しない挙動になるビルドレベルによって記述できる箇所が変わるという3点の理由により全く不十分なのです。順番に見てみましょう。1.行末の;(セミコロン)を強制できないdo-while(0)じゃないバージョンでは行末の;(セミコロン)を強制できません。0;}このように展開されるのでセミコロンが無くてもc++のシンタックス上は問題の無いコードになります。これはc++のシンタックスに準じていないし、コード全体の一貫性も欠くことになります。書けてしまうというのは使う側ではなく、定義した側の責任です。2.記述する場所によっては意図しない挙動になるこのマクロがブロック無しif文の直後で呼ばれた時に意図しない挙動になります。nullptr;ブロック無しif文なんて書くな、カッコ悪いぞ!っていう話ではあるのですが、こう書いた時に以下のように展開されます。(p)と対だったはずのelse節がマクロから展開された方のif文との対になってしまいました。これも使う側ではなく、定義した側の責任です。do-whileで囲んだ最初の定義だと以下のように展開されます。nullptr;3.ビルドレベルによって記述できる箇所が変わるマクロが展開を展開した時にシンタックスエラーになるケースが変わります。なんか処理}if文だけのマクロの場合はこのような書式がc++的に許されてしまいます。デバッグビルド時は問題無いのに、いざリリースしようとするとコンパイルエラーになってしまいます。同じことが非デバッグ時のDEBUG_LOGの定義にも言え、例えば((void)0)を書かずに、展開結果をただ空白にしてしまうと、非デバッグビルド時には、どこにでも記述できるというマクロになってしまいます。0;}このように書いてもエラーになりません。マクロはc++のシンタックスを無視して、どこにでも記述できてしまいます。どこにでも記述させたい明確な理由が無い場合、このような記述はできるべきではありませんし、そもそもデバッグビルド時と記述可能箇所のルールが変わってしまいます。ビルドレベルによって記述可能箇所のルールが変わるのは、単に分かりづらい上に、ビルドレベルを変えたタイミングで、初めてコーディングのミスに気づくことになるので効率も悪いです。いうスキルレベルのプログラマに使われても不具合が起こりにくくなるように、可能な限り、紛れの無いコーディングを促すような設計を心がけましょう。