可変長引数
可変長引数（かへんちょうひきすう）とはプログラミング言語において、関数やメソッドやマクロの引数が固定ではなく任意の個数となっている引数のことである。可変引数、可変個引数とも呼ばれる。そのような関数を可変長引数関数と言う。いくつかの言語では型安全が保証されなくなるので注意が必要である。
C言語
C言語においては printf、scanf といった標準ライブラリの関数が可変長引数をとる代表例である。可変長引数をとる関数のユーザー定義も可能である。信頼できない入力を扱う場合は書式文字列攻撃に注意する必要がある。可変長引数として渡す際に型情報が失われるため、型に関する情報を別途渡すなどする必要がある。
#include <stdarg.h>/* stdarg.h には、マクロ va_start、va_arg、va_end が定義されている。対応する va_start と va_end の呼び出しは、同じ関数内でなければならない。 */double average(int count, ...) {
  va_list ap;
  double sum = 0;
  int i;
  va_start(ap, count); /* スタック変数のアドレスを参照するため、最後の引数が必要である。 */
  for (i = 0; i < count; ++i) {
    /* スタックに積まれているはずの double 型の値を取り出し、ポインタ変数 ap が次の引数を指すように変更する。 */
    sum += va_arg(ap, double);
  }
  va_end(ap);
  return sum / count;}
呼び出し例:
#include <stdio.h>int main(void) {
  double sum1 = average(3, 1.0, 2.0, 3.0);
  double sum2 = average(4, 1.5, 2.1, -3.0, 0.7);
  printf("%f\n", sum1);
  printf("%f\n", sum2);
  return 0;}
Cプリプロセッサ・マクロ
C言語のプリプロセッサのマクロ定義において、可変長引数マクロには、以前はトリック的な方法が使われていたが、C99で本物の可変長引数マクロが標準化された。__VA_ARGS__という識別子を使用する。
次のような関数の呼出しに展開されるマクロを定義したいとする。関数が可変長引数をとるため、機能を制限したくなければ、マクロも可変長引数をとるようにしたい。
void realdbgprintf(const char *sourceFilename, int sourceLineNumber, const char *formatString, ...);
C++での可変長引数マクロの設計に問題があるため、以下に示すような定義は行えない。
#define dbgprintf(cformat, ...) realdbgprintf(__FILE__, __LINE__, cformat, __VA_ARGS__)
この書き方だと、dbgprintf("Hello")と記述した際にrealdbgprintf(__FILE__, __LINE__, "Hello", )と展開される。関数の引数リストをカンマで終えると構文エラーを起こすため、printfのような使い勝手は得られない。
gccの独自構文では##__VA_ARGS__という識別子もサポートしている。これを利用することにより引数が0のものも定義できる。
#define dbgprintf(cformat, ...) realdbgprintf(__FILE__, __LINE__, cformat, ##__VA_ARGS__)
gcc以外でも使用するためには__VA_ARGS__を使うほかないが、その場合は書式文字列も含めて可変長引数として渡す必要がある。
#define dbgprintf(...) realdbgprintf(__FILE__, __LINE__, __VA_ARGS__)
C++
可変長引数テンプレートがC++11でサポートされた。
template<typename... Args> class tuple;
このtupleクラステンプレートは、テンプレート引数としていくらでも型名を取れる:
tuple<std::vector<int>, std::map<std::string, std::vector<int>>> someTuple; // tuple インスタンス。tuple<> emptyTuple;
std::tupleとしても標準化されている。
また、C++11ではC99との互換性向上のため、可変長引数マクロが標準化された (N1653)。
英語
variadicは「可変長引数の」「可変個引数の」という意味の形容詞である。C言語などでは可変長引数のことを「variable argument」と呼ぶ。辞典などでは直訳して「変数引数」とされていることがあるが、これは誤訳である。なお、「変数引数」という言葉は、Pascalなどで変数渡しに使用される「variable parameter」の定訳であり、これは可変長引数とは違うものを指す。したがって、可変長引数のことを「変数引数」と呼ぶのは混乱の原因となる。