Cのプログラムでこれまではデバッグ情報を普通にstderrに書いていたが,
そうするとプログラムの出力と混じってしまう上, 後から検証するのも難しくなる。
ふと気がついて, 下のような dprintf() 関数を書いて, 便利に使っている。
/*
debug.c
$Id: debug.c,v 1.3 2006/12/07 09:46:58 dmochiha Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "debug.h"
#define DEBUG_FILE "log.debug"
static FILE *dp = NULL;
int
dprintf (const char *fmt, ...)
{
int n;
va_list ap;
if (dp == NULL)
{
if ((dp = fopen(DEBUG_FILE, "w")) == NULL)
{
fprintf(stderr, "dprintf: can't open debugging output: %s\n",
DEBUG_FILE);
exit(1);
}
}
va_start(ap, fmt);
n = vfprintf(dp, fmt, ap);
fflush(dp);
va_end(ap);
return n;
}
何も考えず, 普通に
dprintf("table[%d] = %g\n", i, table[i]);
のようにすると, 固定ファイル(上では "log.debug")に結果が蓄積される。
必要なら, #ifdef DEBUG .. #endif で囲ってもいいかも。
この結果は途中で tail -f で見ることができるし(そのために上ではfflush()
している), 結果も残るので, 後から検証するのにも便利。
プログラムの出力と混ざらないので, 実験がとてもしやすくなった。
*1
可変長引数を取るのは Lisp では常識に近いのに, C言語の普通の講座では
ほとんど採り上げられていないような気がする。
最初にC言語を習った時に気になって
聞いたら, vararg.h を使えと言われたが, その当時はよくわからなくて使えなかった。
上は簡単な例ですが, 今頃になって大分わかってきたような気もする。
*1: 上でdpをクローズしていないのはわざとで, debug_finish()などを一々
実行しなくてすむようにするためです。