返回信息流#ifndef _SYS_VARARGS_H_
#define _SYS_VARARGS_H_
#if defined(vax) || defined(sun3) || defined(mips) || defined(i386) || defined(mac2)
#define va_dcl int va_alist;
typedef char * va_list;
#define va_start(pvar) (pvar) = (va_list)&va_alist
#define va_end(pvar)
#ifdef mips
# define va_arg(pvar, type) ((type *)(pvar = \
(va_list) (sizeof(type) > 4 ? ((int)pvar + 2*8 - 1) & -8 \
: ((int)pvar + 2*4 - 1) & -4)))[-1]
#else /* mips */
#define va_arg(pvar,type) ( \
(pvar) += ((sizeof(type)+3) & ~0x3), \
*((type *)((pvar) - ((sizeof(type)+3) & ~0x3))) )
#endif /* mips */
#endif /* vax */
为什么代码中
#define va_arg(pvar,type) ( \
(pvar) += ((sizeof(type)+3) & ~0x3), \
*((type *)((pvar) - ((sizeof(type)+3) & ~0x3))) )
pvar加了一个对type取int上整之后,立刻又减去了呢?
怎么达到取下一个参数的目的的
这是一条镜像帖。来源:北邮人论坛 / cpp / #92858同步于 2016/7/29
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
可变参数理解的问题
LoveXY
2016/7/29镜像同步2 回复
订阅后,新回复会通过你的通知中心匿名送达。
2 条回复
1. 為什麼減去:因為那個 `va_arg()` 定義裡面是個逗號運算符,只返回後一個表達式的結果,先把 `pvar` 指向下一個參數,然後減回來取值
2. 怎麼取下一個參數:表達式 `(sizeof(type)+3) & ~0x3` 計算這個 `type` 類型的參數佔幾個 4 字節大小,用指針取一下就可以了
3. 話說 `va_start` 不應該是兩個參數嗎……
va确实很恶心。调用者调用函数,肯定仍然会按照calling convention来调用。比如x86_64的前6个整数参数用rdi,rsi,rdx,rcx,r8,r9,前若干个浮点参数用xmm0, xmm1, ...,其余的在栈上按顺序分配。然后,怎么给程序员提供可编程接口,来通过va_start,va_arg等宏来处理这样传进来的参数,就看实现了。我想为了便于实现,肯定会把寄存器里的东西放到内存里,以便留出寄存器来做别的工作,以及便于用循环、指针来解析参数。当然,也不一定。都看实现。
至于va_start要用第一个形参作为参数,应该是历史遗留问题,想用这种方法获得第一个参数所在的栈上的地址。曾经有一段时间,函数的prolog和epilog都是系统规定的,可能已经用汇编语言写死了,编译器并没有控制权。后来,编译器开始负责所有的机器码的生成。所以,第一个参数在哪里,编译器肯定知道(而且不一定在栈上,一般是在寄存器里,x86是个很大的例外)。