免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3725 | 回复: 2
打印 上一主题 下一主题

va_list这样的东东究竟是怎么回事? [复制链接]

论坛徽章:
0
1 [报告]
发表于 2004-10-18 17:24 |显示全部楼层

va_list这样的东东究竟是怎么回事?

原来va_list就是char *啊,嘿嘿现在看看,原来是这样,以下为个人看法,
如果对了,纯属巧合
==================================
假设写了一个变参数个数的函数如下
void test(char *fmt, ...)
{
        va_list myVa;
        va_start(myVa, fmt);
        ....
}

根据楼主提供的宏扩展以后
myVa = ((char*)&fmt + (sizeof(fmt)+sizeof(int)-1)&~(sizeof(int)-1)

sizeof(int) = 2; //16机器, 0x0010                                        sizeof(int)-1=0x0001
sizeof(int) = 4; //32机器, 0x0000 0100                       
                                sizeof(int)-1=0x0000 0011
sizeof(int) = 8; //64机器, 0x0000 0000 0000 1000       
                                sizeof(int)-1=0x0000 0000 0000 0111

思路:
变参数的函数, 用va_start来获得第一个变参的地址
fmt为函数调用中上一个参数在栈中的地址,
sizeof(fmt)为该参数的实际大小,
本来fmt的地址+fmt大小(也就是地址偏移应该已经可以获得下一个参数的地址了)
为什么还有sizeof(int)呢, 考虑函数调用可能有类似字节对齐的要求,
那么sizeof(int)在16,32,64位机器上分别为2,4,8

所以对sizeof(fmt)有两种情况, 一是已经符合要求, 刚好对齐
一是不符合要求, 不对齐, 那么根据要求是要多算上1,3,7个字节的
那么sizeof(fmt)+sizeof(int)-1
对第一种情况, 多加了几个字节, 是需要去掉的
对第二种情况, 加上后可能刚好满足要求, 也可能又多出了几个字节

对这两种情况都有多出的字节, 但很明显多出的字节小于1,3,7
所以看看& ~(sizeof(int)-1) 明白了吧, 把末尾几位都给去掉了

对2来说0~1是没有意义的
对4来说0~3是没有意义的
对8来说0~7是没有意义的
所以分别将sizeof(int)-1取反后再&, 将末尾的去掉

那么就大功告成了,也就是说是根据上一个参数的地址和大小取到下一个参数的地址

论坛徽章:
0
2 [报告]
发表于 2004-10-18 17:27 |显示全部楼层

va_list这样的东东究竟是怎么回事?

va_arg没再想过,偶已经很满足了,留给别人思考吧,

论坛徽章:
0
3 [报告]
发表于 2004-10-18 18:02 |显示全部楼层

va_list这样的东东究竟是怎么回事?

不知道楼上是来干什么的,有没有看清别人在问什么...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP