[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.15 改変数引数を持つマクロ

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

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

args残りの引数である。 呼び出し側と同じだけの、ゼロ個以上の引数を取る。 これら全ての引数とその間にカンマを加えたものが、args の 値となり、args が使われるマクロ本体に代入される。 結局、この例は以下のように展開される。

 
eprintf ("%s:%d: ", input_file_name, line_number)
→
fprintf (stderr, "%s:%d: " , input_file_name, line_number)

文字列定数の直後のカンマは eprintf の定義から来たものであるのに 対し、最後のカンマは args の値から来たものであることに注意。

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

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

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

 
fprintf (stderr, "success!\n")

これは、GNU C プリプロセッサの特別な機能である。 ‘##’ の後の残りの引数が空の場合の 、先行する、 マクロ定義から来る非空白文字の列を捨てさる。 (もう一つ別のマクロ引数が先行する場合は、何も捨てない。)

最後の先行する非空白文字の列の代わりに、最後のプリプロセッサ・トークンを 捨て去ったほうが良いのかもしれない。実際、いつかはこの機能をそのように 変えたいと思う。我々としては、マクロ定義を書くときは、 先行する非空白文字の列をちょうど一個のトークンとなるように書いて、 我々がこの機能の定義を変えたときにも意味が変わらないようにすることを お勧めする。


This document was generated using texi2html 1.78.