我认为该函数完成后会从堆栈中删除参数,但printf等函数在调用堆栈时会从堆栈中删除可变数量的参数。参数在变量参数函数中如何传递到堆栈上?
它如何知道从堆栈中删除多少个参数?是否有一个秘密参数来指定传递了多少个参数?
感谢
我认为该函数完成后会从堆栈中删除参数,但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);
是否意味着可变参数的函数必须有一些争论,确定参数的个数来被访问(如printf中的格式字符串)? –
@dhgfdg dgdfgds:无法知道已经传递了多少个参数,所以是_variable参数list_几乎总是需要指定其内容的另一个参数。 –
没有“C调用约定”这样的东西。任何能够以与抽象机匹配的方式满足可观察函数调用行为的需求的调用约定是可行的实现。 –