STDARG(3)

名称
stdarg - 変数引数リスト

書式
#include <stdarg.h> void va_start(va_list ap, last) type va_arg(va_list ap, type) void va_end(va_list ap)

解説
関数はさまざまな型のさまざまな数の引数で呼び出せます。 インクルードファイル <stdarg.h> は、型 (va_list) を宣言し、呼び出される関数には数字と型が 未知の引数リストをステップするために 3 つのマクロを定義します。

呼び出される関数は、 va_list 型のオブジェクトを宣言する必要があります。 これは、マクロ va_start(), va_arg(), va_end() によって使用されます。

va_start() マクロは、 va_arg() と va_end() が後に使用する ap を初期化し、 最初に呼び出す必要があります。

パラメータ last は変数引数リストの前の最後のパラメータの名前です。 すなわち、呼び出し関数が型を認識している最後のパラメータです。

このパラメータのアドレスは va_start() マクロで使用されるので、 レジスタ変数または関数または配列型として宣言してはなりません。

va_start() マクロは値を返しません。

va_arg() マクロは、呼び出しの次の引数の型と値がある式に展開されます。 パラメータ ap は、 va_start() によって初期化される va_list ap です。 va_arg() の呼び出しごとに ap は修正され、次の呼び出しが次の引数を返します。 パラメータ type は、指定型のオブジェクトを指すポインタの型が * を type に追加するだけで得られるように指定された型名です。

次の引数がない場合、または type が (デフォルトの引数生成に従って生成されたような) 実際の次の引数の型と互換性がない場合、 ランダムなエラーが発生します。

va_start() マクロの後の最初の va_arg() マクロの使用によって、 last の後の引数が返されます。 連続的な呼び出しによって、残りの引数の値が返されます。

va_end() マクロは、変数引数リストが va_start() によって初期化される関数の正常な 戻りを取り扱います。

va_end() マクロは値を返しません。

使用例
関数 foo は、形式キャラクタのストリングを取り上げ、型を基礎にして各形式 キャラクタに対応する引数を印刷します。

    void foo(char *fmt, ...)
    {
    	va_list ap;
    	int d;
    	char c, *s;
    	va_start(ap, fmt);
    	while (*fmt)
    		switch(*fmt++) {
    		case 's':			/* ストリング */
    			s = va_arg(ap, char *);
    			printf("string %s\n", s);
    			break;
    		case 'd':			/* 整数 */
    			d = va_arg(ap, int);
    			printf("int %d\n", d);
    			break;
    		case 'c':			/* キャラクタ */
    			/* 注意: キャラクタは整数を生成する。 */
    			c = va_arg(ap, int);
    			printf("char %c\n", c);
    			break;
    		}
    	va_end(ap);
    }

規格
va_start(), va_arg(), va_end() の各マクロは isoC に準拠しています。

互換性
これらのマクロは、置き換えられる歴史的なマクロと互換性がありま せん 。 後方互換バージョンはインクルードファイル <varargs.h> の中にあります。

バグ
varargs マクロと違って、 stdarg マクロでは、プログラマは、固定した引数のない 関数を作成することができません。この問題は、主に varargs コードを stdarg コードに変換するときに作業を生じさせますが、 vfprintf(3) のように、 va_list 引数を取る関数にすべての引数を渡そうとする各種の関数についても困難を 生じさせます。