毫无疑问,C的每个其他学生都注意到了这一点;这对我来说是新的.
如果我宣布:
int xlate( void *,... );
然后以几种不同的方式定义xlate()(也许所有定义,但一个是#ifdef-ed out):
int xlate ( char *arg1 ) { ... } int xlate ( int arg1,char *arg2,int arg3 ) { ... } int xlate ( char arg1,int *arg2 ) { ... }
并省略任何提及va_list – 从不提及它 – 在每一个
xlate()的定义;然后调用xlate()遵守其中一个
几个定义,似乎每个编译版本的xlate()
按照我想要的方式工作,至少在gcc和msvc下.
在C99下保证这种放松,不严格,慷慨的编译器行为吗?
谢谢!
– 皮特
解决方法
除了caf的回答:
由于存在一些问题,这不起作用,标准除了禁止这样的事情之外别无能为力:
原型告诉调用方在调用函数时必须如何执行参数转换.您提供的示例已经不能可靠地用于第一个参数.你声明它为void *然后在另一个中声明为int.由于两者可能具有不同的宽度,因此在大多数64位体系结构中,您的代码将被判定为失败.
更糟糕的是,……符号告诉主叫方对剩余的参数应用默认促销.例如,如果您的实现期望浮动,则调用方将始终提供双倍,并且再次,您的代码将严重崩溃(=最近).
然后,现代体系结构具有复杂的规则,它们将哪些类型的参数放在堆栈中并保存在寄存器中.这取决于参数的类型,例如整数和浮点具有不同的寄存器集.所以这会让你的论点完全错误.