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下保证这种放松,不严格,慷慨的编译器行为吗?
谢谢!
- 皮特
除了咖啡馆的回答:
由于几个问题,这行不通,并且标准除了禁止这样的事情之外别无他法:
原型告诉调用方在调用函数时必须如何执行参数转换。您给出的示例对于第一个参数来说已经无法可靠地工作。你先声明它void*,然后再int声明另一个。由于两者可能具有不同的宽度,因此您的代码在大多数 64 位架构上注定会失败。
更糟糕的是,该...符号告诉调用方对其余参数应用默认提升。例如,如果您的实现期望float调用方始终提供 a double,那么您的代码将严重崩溃(=最近)。
然后,现代体系结构具有复杂的规则,它们将哪些类型的参数放在堆栈上以及哪些类型保存在寄存器中。这取决于参数的类型,例如整数和浮点数具有不同的寄存器组。所以这会让你的论点完全错误。