关于IAR编译器下 va_arg(ap, T) 的定义
绝对神骑 2013-08-15 11:40:11 #if __VA_STACK_DECREASING__
/*
* The expressions handles three cases:
* 1) Access where the type's alignment is larger than the default
* stack alignment. The pointer is aligned before the access.
* 2) Access where the size is the same as the size the value is passed in.
* 3) Access where the size of the type is smaller than the size of the
* passed value.
*/
#define va_arg(ap, T) \
( __ALIGNOF__(T) > __VA_STACK_ALIGN__ \
? ( (*(long *) &(ap)._Ap) += (__ALIGNOF__(T) - 1), \
(*(long *) &(ap)._Ap) &= ~(__ALIGNOF__(T) - 1), \
(*(*(T **) &(ap)._Ap)++)) \
: (_SIZE_ON_STACK(T) == sizeof(T) \
? (*(*(T **) &(ap)._Ap)++) \
: ((ap)._Ap += _SIZE_ON_STACK(T), \
*(T *) ((ap)._Ap - (sizeof(T) + _STACK_ADJUST_AFTER(T))))))
#else /* !__VA_STACK_DECREASING__ */
/*
* Case 1 from above is not handled by the increasing stack (yet)!
*/
#define va_arg(ap, T) \
(_SIZE_ON_STACK(T) == sizeof(T) \
? (*--(*(T **) &(ap)._Ap)) \
: ((ap)._Ap -= _SIZE_ON_STACK(T), \
*(T *) ((ap)._Ap + _STACK_ADJUST_AFTER(T))))
#endif /* __VA_STACK_DECREASING__ */
#else /* _VA_DEFINED */
#define va_start(ap, A) _VA_START(ap, A)
#define va_end(ap) _VA_END(ap)
#define va_arg(ap, T) _VA_ARG(ap, T)
///////////////////////////
#define _SIZE_ON_STACK(T) \
(((sizeof(T) + __VA_STACK_ALIGN__ - 1) / __VA_STACK_ALIGN__) * \
__VA_STACK_ALIGN__)
#define _VA_START(ap, A) (ap._Ap = _CSTD __va_start1())
#define _VA_END(ap) ((void) 0)
#define _VA_ARG(ap, T) \
( __ALIGNOF__(T) > __VA_STACK_ALIGN__ \
? ( (*(long *) &(ap)._Ap) += (__ALIGNOF__(T) - 1), \
(*(long *) &(ap)._Ap) &= ~(__ALIGNOF__(T) - 1), \
(*(*(T **) &(ap)._Ap)++)) \
: (_SIZE_ON_STACK(T) == sizeof(T) \
? (*(*(T **) &(ap)._Ap)++) \
: ((ap)._Ap += _SIZE_ON_STACK(T), \
*(T *) ((ap)._Ap - (_SIZE_ON_STACK(T))))))
//////////////////////////////////////////////////////
请问是否当 __VA_STACK_DECREASING__ 为1时 va_arg(ap, T) 就进入第一种情况 既访问的类型的对齐是大于默认堆栈对齐,指针是一致的访问之前。 但是 我看了网上对va_arg的解释是 ap会指向下一个可变参数的地址啊!上面定义和下面对va_arg(ap,T)定义有什么不同呢?还有stdarg.h这个C标准库中对va_list的定义类型都是为char型的么?求指教 ,谢谢
#ifndef _VA_LIST_DEFINED
typedef char *va_list;
#define _VA_LIST_DEFINED
#endif
#define va_start(ap,v) ap = (va_list)&v + sizeof(v)
#define va_arg(ap,t) (((t *)ap)++[0])
#define va_end(ap)