スポンサーリンク
標準でないのか疑問だったがちょっと(30秒くらい)検索して出てこなかったので誰かの役に立つかもしれない。
以下のDEBUG_INFOマクロは、指定した文を#if 1の時だけ実行する。
#if 0の時は/**/に置き換わる。なお/**/はスペース一個に置き換わる。
以下は初心者にありがちなfloatをループカウンタにする例。
値の推移を表示させたいがリリース時にはいらない時に使う。
#include <stdio.h> // デバッグの時は #if 1 , そうでないときは0を指定 #if 0 #define DEBUG_INFO(a) a #else #define DEBUG_INFO(a) /**/ #endif int main() { int i = 0; float x; for (x = 0.1f; x <= 1.0f; x += 0.1f) { DEBUG_INFO(printf("%.10lf\n", x);) i++; } DEBUG_INFO(printf("%.10lf\n", x);) printf("%d\n", i); }
しかしこのマクロではうまく動いてくれない場合がある。
DEBUG_INFOの中に,(カンマ)があると、関数形式マクロと認識されてしまい、(多分)第二引数だけを指定した状態になり、しかし置換は第一引数に対して行われ、つまり第一引数は存在しないので、結果yが定義されていないというエラーが生じる(のだと思う)。
#include <stdio.h> // デバッグの時は #if 1 , そうでないときは0を指定 #if 1 #define DEBUG_INFO(a) a #else #define DEBUG_INFO(a) /**/ #endif int function( int x DEBUG_INFO(, int y)// エラー 'y':定義されていない識別子です。 ) { return x DEBUG_INFO(*y); } int main() { int a = 10, b = 12; int i = function(a DEBUG_INFO(,b)); printf("%d\n", i); }
C++11以降可変長引数マクロが使えるらしいので、それを使って以下のように書き換える。
#if 1 #define DEBUG_INFO(...) __VA_ARGS__ #else #define DEBUG_INFO(a) /**/ #endif
可変長引数マクロは、... (ドット三つ)で可変長であることを表現し、展開時 __VA_ARGS__ が...に指定した内容に置き換わる。
#include <iostream> // デバッグの時は #if 1 , そうでないときは0を指定 #if 1 #define DEBUG_INFO(...) __VA_ARGS__ #else #define DEBUG_INFO(a) /**/ #endif int function( int x DEBUG_INFO(, int y) ) { return x DEBUG_INFO(*y); } int main() { int a = 10, b = 12; int i = function(a DEBUG_INFO(,b)); printf("%d\n", i); }
標準にないのかこれ。今暇なくて真面目に探せない。