VA_PASS

VA_PASS

出處

http://www.codeproject.com/KB/tips/va_pass.aspx
http://ramaswamy.r.googlepages.com/ellipsis(...)and__va_args__

內文

1

template<byte count>
struct SVaPassNext{
    SVaPassNext<count-1> big;
    DWORD dw;
};
template<> struct SVaPassNext<0>{};
//SVaPassNext - is generator of structure of any size at compile time.

class CVaPassNext{
public:
    SVaPassNext<50> svapassnext;
    CVaPassNext(va_list & args){
        try{//to avoid access violation

            memcpy(&svapassnext, args, sizeof(svapassnext));
        } catch (...) {}
    }
};
#define va_pass(valist) CVaPassNext(valist).svapassnext

#if 0 //using:

void MyVA_Function(szFormat, ...){
    va_list args;
    va_start(args, szFormat);
    SomeOtherVA_Function(szFormat, va_pass(args));
    va_end(args);
}
#endif

2

#define SENTINEL -32768 // Used to mark the end of Variable Argument List

#define MAX_PARAMS 10

struct va_pass_intlist
{
int list[MAX_PARAMS];
va_pass_intlist(va_list & args)
{
va_list countArgs = args;
byte paramCount = 0;

while ( SENTINEL != va_arg(countArgs, int) )
++paramCount;

ASSERT(paramCount <= MAX_PARAMS);
memcpy(this, args, sizeof(int) * paramCount);
}
};

int average(int first, ...)
{
va_list args, params;
params = va_start(args, first);

va_pass_intlist myparams(params);
int count = 0,
sum = sum(first, myparams);

while( SENTINEL != va_arg(args, int) )
++count;

return sum / count;
}

My Modify and Full test Code

  • Portable - test in VC9 , GCC 3.2.2 and GCC 4.2.4
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <memory.h>

#ifdef _MSC_VER
#define SNPRINTF _snprintf
#else
#define SNPRINTF snprintf
#endif

template<char count>
struct SVaPassNext{
    SVaPassNext<count-1> big;
    unsigned int dw;
};
template<> struct SVaPassNext<0>{};

class CVaPassNext{
public:
    SVaPassNext<16> svapassnext;
    CVaPassNext(va_list& args){
        try{
            memcpy(&svapassnext, args, sizeof(svapassnext));
        } catch (...) {}
    }
};

template<char count>
class CVaPassNextN{
public:
    SVaPassNext<count> svapassnext;
    CVaPassNextN(va_list& args){
        try{
            memcpy(&svapassnext, args, sizeof(svapassnext));
        } catch (...) {}
    }
};
#define va_pass(x) CVaPassNext(x).svapassnext
//n need defined in compiler time
#define va_pass_n(x,n) CVaPassNextN<n>(x).svapassnext

int myprint1(char* format,...)
{
    static char tempstr[512];
    va_list list;
    va_start(list,format);
    SNPRINTF(tempstr, 512, format,va_pass(list));
    va_end(list);
    printf(tempstr);
    return 0;
}

int myprint2(char* format,...)
{
    static char tempstr[512];
    va_list list;
    va_start(list,format);
    SNPRINTF(tempstr, 512, format,va_pass_n(list,4));
    va_end(list);
    printf(tempstr);
    return 0;
}

int main(int argc, char* argv[])
{
    myprint1("test1 %d, %s, %d\n", 11, "22" , 33);
    myprint2("test2 %d, %s, %d\n", 11, "22" , 33);
    #ifdef _MSC_VER
    system("PAUSE");
    #endif
    return 0;
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-NoDerivs 3.0 License