スポンサーリンク

C言語でデバッグ用の文をリリース時には無効化するマクロ

標準でないのか疑問だったがちょっと(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);

}

2.応用形

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);

}

あとがき

標準にないのかこれ。今暇なくて真面目に探せない。

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: