これがすべてのコンパイラで機能するかどうかはわかりませんが、これまでのところ機能しています。
void inner_func(int &i)
{
va_list vars;
va_start(vars, i);
int j = va_arg(vars);
va_end(vars); // Generally useless, but should be included.
}
void func(int i, ...)
{
inner_func(i);
}
必要に応じて ... を inner_func() に追加できますが、必要ありません。va_start は指定された変数のアドレスを開始点として使用するため、機能します。この場合、func() で変数への参照を与えています。したがって、そのアドレスを使用して、その後スタック上の変数を読み取ります。inner_func() 関数は、func() のスタック アドレスから読み取ります。したがって、両方の関数が同じスタック セグメントを使用する場合にのみ機能します。
va_start および va_arg マクロは、開始点として var を指定すると、通常は機能します。したがって、必要に応じて、他の関数にポインターを渡し、それらも使用できます。独自のマクロを簡単に作成できます。マクロが行うのは、メモリ アドレスの型キャストだけです。ただし、それらをすべてのコンパイラと呼び出し規約で機能させるのは面倒です。そのため、コンパイラに付属しているものを使用する方が一般的に簡単です。