結構ある要求の一つに、printf のカスタムバージョンを簡単に作りたいというものがありました。例えば、dbg("ok value=%d", val); というようなマクロを呼び出すと、最終的に、printf("debug:ok value=%d", val); のように展開したいというものです。このような方法を実現するためには、今まではいくつかの妥協が必要でした。
しかし、今度の仕様のプリプロセッサを使えばこのような可変長引数を持つマクロが簡単に作成することができるようになるのです。
まず、可変長引数を持つマクロでは、可変長にしたい部分に省略を示す記号「...」をおきます。これは C 言語の省略の記号と同じもので、引数リストの最後にしか置くことができません。この関数型マクロを使うときには、この省略の部分には、まったく引数をかかなくてもいいし、いくつも書いても許されます。また、(1)のように一つも固定部分がないマクロも可能です。そして、マクロの右側ではその部分はマクロ「__VA_ARGS__」でその内容を参照することができます。
これで cpp がますます使いやすくなりましたね。
/*
* cpp: 従来型の可変長引数マクロの実現方法 (c)1999 seclan
* ver1.00 1999/04/05 最初のバージョン
*/
#include <stdio.h>
#include <stdarg.h>
#define dbg(arg) (printf("debug:"), printf arg)
int vadbg(const char *format, ...)
{
int r;
va_list va;
va_start(va, format);
r = printf("debug:");
r += vprintf(format, va);
va_end(va);
return r;
}
main()
{
dbg(("ok value=%d", 1)); //引数を()で括らなくてはならない
vadbg("ok value=%d", 1); //いちいち新たな関数を作成しなくてはならない
}
|
しかし、今度の仕様のプリプロセッサを使えばこのような可変長引数を持つマクロが簡単に作成することができるようになるのです。
/*
* cpp: 新しい C 言語の CPP 可変長引数マクロの例 (c)1999 seclan
* ver1.00 1999/04/05 最初のバージョン
*/
#include <stdio.h>
#define dbg(fmt, ...) printf("debug:" fmt, __VA_ARGS__)
#define adbg(...) printf("debug:" __VA_ARGS__) //(1)これもOK
main()
{
int x = 2, y = 4;
dbg("ok value=%d", 1); //通常の printf のように使える!
dbg("[%u,%u]", x, y); //多くてもOK
adbg("%u", x); //ok
adbg(); //もちろん省略もできる
}
|
まず、可変長引数を持つマクロでは、可変長にしたい部分に省略を示す記号「...」をおきます。これは C 言語の省略の記号と同じもので、引数リストの最後にしか置くことができません。この関数型マクロを使うときには、この省略の部分には、まったく引数をかかなくてもいいし、いくつも書いても許されます。また、(1)のように一つも固定部分がないマクロも可能です。そして、マクロの右側ではその部分はマクロ「__VA_ARGS__」でその内容を参照することができます。
これで cpp がますます使いやすくなりましたね。
by seclan