Zephyr Cradle Diary


2009.06.04 (Thu)

[PG] 可変引数を持つ関数マクロ(C言語)

GNU Cの言語拡張とはいえ、そんなの出来たのか! いや出来そうな気はしてたんだけど、じゃあそれってどう使うんだ? って考えて挫折しました。まあ当然ながら、GCCのリファレンスに書いてあるわけで。(たまたま覗いてたら見つけた)

http://www.sra.co.jp/wingnut/gcc/gcc-j.html#Macro%20Varargs

GNU C では、関数と同じように、マクロも可変数の引数を取ることができる。その場合のマクロの定義構文は関数の場合に使われるものに良く似ている。次に例を示す。

#define eprintf(format, args...) \

 fprintf (stderr, format , ## args)

##というプリプロセッサディレクティブがあるのは、マイナーながら知っていた。前後の文字列を合体させるとか、何このよく判らない用途のプリプロ、とは思ってたけど、まさかこんなところで出会おうとは。

で、##については次のように書かれてました。

## を使う理由は、args に全く引数がない場合を扱うためである。その場合、args の値は空となる。そうすると、マクロ定義中の二番目のカンマが邪魔になる。マクロをそのまま展開すると、以下のようになる。

fprintf (stderr, "success!\n" , )

これは、C の文法として誤ったものになる。## を使うとこの場合のカンマを取り除くので、代わりに以下のようになる。

fprintf (stderr, "success!\n")

なんか小技チックだなあ! でもこれでようやく##の使いどころを知りましたわ。今日の目から鱗でございました。でもまあ、やっぱり他にはないよね##の使い道。

となると、可変引数の関数ポインタってのも出来るのかな。