在C中,来电者是否曾特别对待变体数据?

时间:2017-02-01 19:03:20

标签: c variadic-functions calling-convention

我的理解是C变量参数完全在被调用者的一方处理,即如果用

调用函数f
f(1, 2, 3.0)

无论您是将f声明为

,编译器都会为调用生成相同的代码
void f(int, int, double);

void f(int, int, ...);

这个问题的上下文是this issue,它使用可变参数FFI定义从Rust调用一个非真正可变的C函数。如果variadics从调用者的角度来看并不重要(当然除了类型检查),那么对我来说似乎很奇怪Rust会为函数生成不同的代码,其函数已被声明为variadic。

如果事实上这不是由C规范决定的,而是ABI依赖的,我会对System V ABI的答案最感兴趣,从我读到的内容中我似乎没有表示对来电者方面的任何特殊的可变参数处理。

1 个答案:

答案 0 :(得分:2)

这是一个非ABI特定的答案。

是的,正式调用者可以(并且通常情况下)以特殊方式处理具有可变参数的函数。这实际上就是为什么从标准化时间开始C语言要求所有可变函数在调用之前用原型声明。请注意,尽管可以在C89 / 90中安全地调用未声明的函数,但是这样做的权限并没有扩展到可变参数函数:这些函数总是必须提前声明。否则,行为未定义。

稍微不同的形式,规则仍然在现代C中。尽管后C99 C不再允许调用未声明的函数,但它仍然不需要 prototype 声明。然而,在调用点之前,必须使用原型声明可变参数函数。基本原理是相同的:调用者必须知道它正在调用可变参数函数,并且可能以不同方式处理调用。

从历史上看,有些实现在调用可变参数函数时使用了完全不同的调用约定。