可変個引数マクロを究める!(その2)
こんばんは、めのんです!
前回に引き続き、Cの可変個引数マクロについてのお話です。
前回は、可変個引数の個数がゼロだった場合、つまり、ひとつも引数を渡さなかった場合に、何の工夫もなければコンパイルエラーになってしまうと書きました。 この問題の解決方法はいくつかあると思うのですが、私にわかる範囲で書いてみたいと思います!
GNU拡張
もともと、この可変個引数マクロというのは、GNU C Compiler(GCC)の独自拡張でした。 それが、C99からCの標準規格に取り込まれたと聞いています。
GCCの独自拡張、つまりGNU拡張でも、可変個引数がゼロ個だった場合の問題には気付いていたようで、しっかり解決策が用意されていました。 最初のころのGNU拡張では、次のように書いたそうです。
#define eprintf(format, args...) fprintf(stderr, (format), ## args)
上の例では、「args...」の部分が可変個引数にあたります。 そして、「##」に続けて「args」を展開するように記述しています。
この「##」がポイントで、可変個引数がひとつもなかった場合に、最後のカンマを削除するための記号とのことです。 ちなみに「args」というのは仮引数名なので、他の名前でも問題ありません。
最近のGCCのドキュメントでは、C99にあわせてVA_ARGSを使って説明しています。 その場合も、「##」の使い方は同じです。
標準C規格
C99で導入された可変個引数マクロでは、必ずVA_ARGSを使います。 でも、GNU拡張のような「##」はサポートされていません。 なので、可変個引数がひとつもない場合は困ってしまいます。
これは誰もが問題と考えるようですね。
Cの次期標準規格では、VA_OPTというのが導入されそうです。 これによって、最後のカンマを取り除くことができます。 VA_OPTはC++でも導入が予定されているようですね。
次回は、もう少し別の切り口から、この問題に取り組んでみたいと思います。
それでは!