この関数は、実行後にスタックからパラメーターを削除すると思いましたが、printfのような関数は、呼び出されたときにスタックから可変数のパラメーターを削除します。
スタックから削除するパラメーターの数をどのように知るのですか?渡される引数の数を指定するための秘密の引数はありますか?
ありがとう
Cの呼び出し規約では、スタックからパラメーターをポップする責任があるのは呼び出し元であり、呼び出し先ではないことを指定しています。そのため、可変引数リストを持つ関数はである必要がありますcdecl
。それで、
関数は、実行後にスタックからパラメーターを削除すると思いました。
これは特定の呼び出し規約にのみ当てはまり、Cの呼び出し規約には当てはまりません。
スタックから削除するパラメーターの数をどのように知るのですか?渡される引数の数を指定するための秘密の引数はありますか?
そうではなく、秘密の議論もありません。
呼び出し元関数はスタックをクリーンアップします(正しい呼び出し規約で)。コンパイラはそのためのコードを生成します。コンパイラは、引数リストに渡した引数の数を正確に把握しているコンパイラです。これは、コンパイラがそれをコンパイルしたためです。
呼び出し元のコードはスタックをクリーンアップし、呼び出された関数が、実行したいことに対して「十分な」引数が渡されたことを正しく判断する必要があります。これは、それ自体が引数である必要はありません。次のようになります。
int sum(int first, ...)
{
int s = first;
int v;
va_list va;
va_start(va, first);
while (v = va_arg(va, int) != -1)
{
sum += v;
}
va_end(va);
return sum;
}
x = sum(1, 2, 3, -1);
y = sum(1, 2, 3, 4, 5, 6, 7, 8, 9, -1);
varargs関数の引数の数へのリンク