- 论坛徽章:
- 0
|
Linux2.6.28的内核:
linux+v2.6.28/include/acpi/platform/acenv.h:
typedef char *va_list;
/*
275 * Storage alignment properties
276 */
277#define _AUPBND (sizeof (acpi_native_int) - 1) //acpi_native_int 为32位(根据机子字数而定)
278#define _ADNBND (sizeof (acpi_native_int) - 1)
/*
292 * Variable argument list macro definitions
293 */
294#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd)))
295#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
296#define va_end(ap) (void) 0
297#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
我的测试源代码如下:
#include <stdio.h>
#include <stdarg.h>
double sum_fun(int num, ...);
int main()
{
double d;
d = sum_fun(2, 5.5, 6.5);
return 0;
}
double sum_fun(int num, ...)
{
double sum = 0.0;
double t;
va_list argptr;
va_start(argptr, num);
for(; num; num--){
t = va_arg(argptr, double);
sum = sum + t;
}
va_end(argptr);
return sum;
}
/********************************************************************************/
这里假设 &argptr = 0xbff69cd4, &num = 0xbff69ce0。
首先解析va_start:
va_start(argptr, num);
argptr = (char *)&num + (sizeof(num) + 3) & ~(3) = 0xbff69ce0 + (0x00000007 & 0xFFFFFFF3) = oxbff69ce4
即 argptr 指向了下一个参数的地址
再来解析 va_arg:
t = va_arg(argptr, double);
*(double *)( ((argptr) += ( (sizeof(double) + 3) & ~(3)) ) - ( (sizeof(double) + 3) & ~(3)) ) )
= *(double *)(argpter + 8-8
这样的话等于没有改变argptr啊。它怎么可能指向下一个参数的地址呢? |
|