varargs是否提供了一种穷人的多态性?

Pet*_*son 6 c variadic-functions

毫无疑问,C的每个其他学生都注意到了这一点; 这对我来说是新的.

如果我宣布:

int xlate( void *, ... );
Run Code Online (Sandbox Code Playgroud)

然后xlate( )以几种不同的方式定义(也许所有定义,但一个定义#ifdef出来):

int xlate ( char *arg1 ) { ... }

int xlate ( int arg1, char *arg2, int arg3 ) { ... }

int xlate ( char arg1, int *arg2 ) { ... }
Run Code Online (Sandbox Code Playgroud)

并且在xlate()的每个定义中省略对va_list的任何提及 - 从不提及它.然后调用xlate()遵循其中的一个定义,似乎xlate()的每个编译版本都按照我想要的方式工作,至少在gcc和msvc下.

在C99下保证这种放松,不严格,慷慨的编译器行为吗?

谢谢!

- 皮特

Jen*_*edt 3

除了咖啡馆的回答:

由于几个问题,这行不通,并且标准除了禁止这样的事情之外别无他法:

原型告诉调用方在调用函数时必须如何执行参数转换。您给出的示例对于第一个参数来说已经无法可靠地工作。你先声明它void*,然后再int声明另一个。由于两者可能具有不同的宽度,因此您的代码在大多数 64 位架构上注定会失败。

更糟糕的是,该...符号告诉调用方对其余参数应用默认提升。例如,如果您的实现期望float调用方始终提供 a double,那么您的代码将严重崩溃(=最近)。

然后,现代体系结构具有复杂的规则,它们将哪些类型的参数放在堆栈上以及哪些类型保存在寄存器中。这取决于参数的类型,例如整数和浮点数具有不同的寄存器组。所以这会让你的论点完全错误。