关于va_arg中的type

简单的说,我们用va_arg(ap,type)取出一个参数的时候,
type对不能为以下类型:
——charsigned charunsigned char
——shortunsigned short
——signed shortshort intsigned short intunsigned short int
——float


一个简单的理由是:
——调用者绝对不my_printf传递以上类型的实际参数


在C语言中,调用一个不带原型声明的函数时:
调用者会对每个参数执行“默认实际参数提升(default argument promotions)”。

同时,对可变长参数列表超出最后一个类型声明的形式参数之后的每一个实际参数,也将执行上述提升工作。
提升工作如下:
——float类型的实际参数将提升到double
——char、short和相应的signed、unsigned类型的实际参数提升到int
——如果int不能存储原值,则提升到unsigned int

然后,调用者将提升后的参数传递给被调用者。
附录:

在《C语言程序设计》对可变长参数列表的相关章节中,并没有提到这个陷阱。
但是有提到默认实际参数提升的规则:

在没有函数原型的情况下,char与short类型都将被转换为int类型,float类型将被转换为double类型。
                ——《C语言程序设计》第2版  2.7 类型转换 p36



在其他一些书籍中,也有提到这个规则:


事情很清楚,如果一个参数没有声明,编译器就没有信息去对它执行标准的类型检查和转换。
在这种情况下,一个char或short将作为int传递,float将作为double传递。
这些做未必是程序员所期望的。
脚注:这些都是由C语言继承来的标准提升。
对于由省略号表示的参数,其实际参数在传递之前总执行这些提升(如果它们属于需要提升的类型),将提升后的值传递给有关的函数。——译者注
                ——《C++程序设计语言》第3版-特别版 7.6 p138

…… float类型的参数会自动转换为double类型,short或char类型的参数会自动转换为int类型 ……
                ——《C陷阱与缺陷》 4.4 形参、实参与返回值 p73


这里有一个陷阱需要避免:
va_arg宏的第2个参数不能被指定为charshort或者float类型。
因为char和short类型的参数会被转换为int类型,而float类型的参数会被转换为double类型 ……
例如,这样写肯定是不对的:
c = va_arg(ap,char);
因为我们无法传递一个char类型参数,如果传递了,它将会被自动转化为int类型。上面的式子应该写成:
c = va_arg(ap,int);
                ——《C陷阱与缺陷》p164

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值