めのん@ひとりプログラミング同好会

このブログはすべてフィクションであり、実在の人物、団体とは一切関係ありません

可変個引数マクロを究める!(その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_OPTC++でも導入が予定されているようですね。

次回は、もう少し別の切り口から、この問題に取り組んでみたいと思います。

それでは!