c - Can I pass an array type before "... " ? Where can I find the macro code for va_* -


  1. i read man page va_start , this:

    the argument last name of last argument before variable argument list, is, last argument of calling function knows type.

    because address of argument may used in va_start() macro, it should not declared register variable, or function or array type.

    i tried code , works well, makes me confused.

    #include <stdio.h> #include <stdarg.h>   void va_func(int i[3],...); int main() {       int m[3] = {0,1,2};       va_func(m,4,5,5,6);       return  0;  }   void va_func(int m[5],...)// pass array type here before "..."  {       int i,j;       va_list ap;       va_start(ap,m);       for(i = 0; < 4 ;i++)       {           j = va_arg(ap,int);           printf("argv[%d] %d\n",i,j);       }       va_end(ap);  } 
  2. then want read code of va_* macros. nothing <stdarg.h> , <cstdarg>. can hacker tell me how , can learn va_*things?


here current problem:

i want write open(const char *path,int oflag, ...); function. hope call open , error test.

int open(const char * path,int oflag, ...) {     int rt;     rt = open(path,oflag,...)// don't know how now.     if(rt == -1)      err_deal_func();     else      return rt; } 

the c runtime provides no way know how many arguments passed. therefore, it's not possible forward arguments easily. functions accept forwarded arguments accept va_list object (see vprintf instance).

you need understand parameters passed able tell how many received. printf able reading format string, , each time sees placeholder in string, reads next parameter; if feed incorrect format string or incorrect parameters, you're going crash.

this open does, too:

the oflag argument may indicate file created if not exist (by specifying o_creat flag). in case, open requires third argument mode_t mode; file created mode mode described in chmod(2) , modified process' umask value (see umask(2)).

that is, not seek read third parameter if oflag doesn't include o_creat. need well, , can see, it's gory.

if you're doing c++ (and not plain old c), suggest use function overloads, has added benefit of being type-safe (and it's huge benefit):

int open(const char * path,int oflag) {     int rt = open(path,oflag);     if(rt == -1)      err_deal_func();     else      return rt; }  int open(const char * path,int oflag,mode_t mode) {     int rt = open(path,oflag,mode);     if(rt == -1)      err_deal_func();     else      return rt; } 

if need in c (and not c++), need use oflag parameter determine if need read additional parameter.

int open(const char* path, int oflag, ...) {     int rt;     if ((oflag & o_creat) == o_creat)     {         // have o_creat, means passed 3 arguments         // declare argument list         va_list ap;         // create argument list starting after `oflag` argument         va_start(ap, oflag);         // read next argument in `ap` `mode_t` variable         mode_t mode = va_arg(ap, mode_t);         // there no more arguments read, clean list         va_end(ap);          // finally, call `open` passing additional parameter         rt = open(path, oflag, mode);     }     else         rt = open(path, oflag);      if (rt == -1)         err_deal_func();     else         return rt; }