Cautions for C length-alterable parameters

来源:互联网 发布:淘宝低价手机骗局 编辑:程序博客网 时间:2024/05/21 02:21
C/C++ use va_list,va_start,va_arg and va_end(all defined in header file<stdarg.h>) to process with functions that have length-alterable parameters like this:
void Foo(int a,...);

the defination of va_macro:
typedef 
char* va_list;               
#define va_start(ap,p) (ap=(char*)(&(p)+1)) 
#define va_arg(ap,type)((type*)(ap+=sizeof(type)))[-1] 
#define va_end(ap) 
    or
typedef 
char* va_list; 
#define _intsizeof(n)  ((sizeof(n)+sizeof(int)-1)&~(sizeof(int)-1)) 
#define va_start(ap,v) (ap =(va_list)&v+_intsizeof(v)) 
#define va_arg(ap,t)   (*(t*)((ap+=_intsizeof(t))-_intsizeof(t))) 
#define va_end(ap)     (ap=(va_list)0)

in function like this:
template
<typename T>
void Foo(int n,...)
{
    
const int total=n;
    va_list args;
    va_start(args,n);

    
for(;n>0;--n)
        num[total
-n]=va_arg(args,T);//external defination for num[]
    va_end(args);
}


if we use it like this:
void TestFoo1()
{
    Foo
<double>(5,1,2,3,4,5);
}

it would never 
get the correct answer because the arguments that pushed into the stack from the 2rd to 5th parameters namely numbers 1 to 5 would be processed like int,not double.At the time the arguments that been pushed into stack,the function wont't know that it would be process like double.

We can 
do the call explicitly like this:
Foo
<double>(2,double(1),double(2));
or
double a=1,b=2;
Foo
<double>(2,a,b);

Let
's go ahead for another function;
void TestFoo2()
{
    Foo
<float>(2,float(1),float(2));
}


it won
't work as the float number will be updated into double even if you declared it explicitly.Be careful!
 
原创粉丝点击