鱼C论坛

 找回密码
 立即注册
查看: 1588|回复: 2

[已解决]va_start()的第二个参数的意义

[复制链接]
发表于 2021-5-27 22:25:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
va_start(ap,v); 为什么第二个参数必须得是最后一个固定参数(...左边那个)
百度查的:
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
我的理解:
是不是将ap指向第一个可变参数(不算已经确认的形参)  

那va_arg(ap,类型)  的工作原理是啥   

这个类型是当前指针指向的类型还是     下一个形参的类型,看很多地方都说第二个参数是下一个形参的类型   
如果是下一个参数的类型   那怎么知道第一个可变参数的类型呢


最佳答案
2021-5-28 10:44:58
这是 stdarg.h 的源代码
#ifndef _STDARG_H
#define _STDARG_H

typedef char *va_list;

/* Amount of space required in an argument list for an arg of type TYPE.
   TYPE may alternatively be an expression whose type is used.  */

#define __va_rounded_size(TYPE)  \
  (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))

#ifndef __sparc__
#define va_start(AP, LASTARG)                                                 \
 (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
#else
#define va_start(AP, LASTARG)                                                 \
 (__builtin_saveregs (),                                                \
  AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
#endif

void va_end (va_list);                /* Defined in gnulib */
#define va_end(AP)

#define va_arg(AP, TYPE)                                                \
 (AP += __va_rounded_size (TYPE),                                        \
  *((TYPE *) (AP - __va_rounded_size (TYPE))))

#endif /* _STDARG_H */
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-5-28 10:44:58 | 显示全部楼层    本楼为最佳答案   
这是 stdarg.h 的源代码
#ifndef _STDARG_H
#define _STDARG_H

typedef char *va_list;

/* Amount of space required in an argument list for an arg of type TYPE.
   TYPE may alternatively be an expression whose type is used.  */

#define __va_rounded_size(TYPE)  \
  (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))

#ifndef __sparc__
#define va_start(AP, LASTARG)                                                 \
 (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
#else
#define va_start(AP, LASTARG)                                                 \
 (__builtin_saveregs (),                                                \
  AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
#endif

void va_end (va_list);                /* Defined in gnulib */
#define va_end(AP)

#define va_arg(AP, TYPE)                                                \
 (AP += __va_rounded_size (TYPE),                                        \
  *((TYPE *) (AP - __va_rounded_size (TYPE))))

#endif /* _STDARG_H */
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-5-28 11:23:22 | 显示全部楼层
#define va_arg(ap,t)      ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数地址
// 将( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )拆成:
/* 指针ap指向下一个参数的地址*/
1.ap += _INTSIZEOF(t);           // 当前,ap已经指向下一个参数了
/* ap减去当前参数的大小得到当前参数的地址,再强制类型转换后返回它的值*/
2.return *(t *)( ap - _INTSIZEOF(t))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-14 14:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表