va_arg(9F)




NAME

     va_arg, va_start, va_copy, va_end - handle variable argument
     list


SYNOPSIS

     #include <sys/varargs.h>

     void va_start(va_list pvar, void parmN);

     (type *)

     va_arg(va_list pvar, type);

     void va_copy(va_list dest, va_list src);

     void va_end(va_list pvar);


INTERFACE LEVEL

     Solaris DDI specific (Solaris DDI).


PARAMETERS

  va_start()
      pvar Pointer to variable argument list.

     name  Identifier of  rightmost  parameter  in  the  function
           definition.

  va_arg()
      pvar Pointer to variable argument list.

     type  Type name of the next argument to be returned.

  va_copy()
      dest Destination variable argument list.

     src   Source variable argument list.

  va_end()
      pvar Pointer to variable argument list.


DESCRIPTION

     This set of macros allows portable  procedures  that  accept
     variable  argument  lists  to be written. Routines that have
     variable argument lists  but do not use the varargs() macros
     are  inherently non-portable, as different machines use dif-
     ferent argument-passing conventions. Routines that accept  a
     variable  argument list can use these macros to traverse the
     list.

     va_list is  the  type  defined  for  the  variable  used  to
     traverse the list of arguments.

     va_start() is called to initialize  pvar to the beginning of
     the  variable  argument  list.  va_start()  must  be invoked
     before any access to the unnamed  arguments.  The  parameter
     name  is  the  identifier  of the rightmost parameter in the
     variable parameter list in the function definition (the  one
     just   before  the  ", ...").  If this parameter is declared
     with the register storage class or with a function or  array
     type,  or  with  a type that is not compatible with the type
     that results after application of the default argument  pro-
     motions, the behavior is undefined.

     va_arg() expands to an expression  that  has  the  type  and
     value  of the next argument in the call.  The parameter pvar
     must be  initialized  by   va_start().  Each  invocation  of
     va_arg()  modifies   pvar  so  that the values of successive
     arguments are returned in turn.  The parameter type  is  the
     type name of the next argument to be returned. The type name
     must be specified in such a way that the type of pointer  to
     an  object  that  has  the specified type can be obtained by
     postfixing a * to  type. If there is no  actual  next  argu-
     ment,  or  iftype  is  not  compatible  with the type of the
     actual next argument (as promoted according to  the  default
     argument promotions), the behavior is undefined.

     The va_copy() macro  saves  the  state  represented  by  the
     va_list  src in the va_list dest. The va_list passed as dest
     should not be initialized by a previous call  to  va_start()
     It  then must be passed to va_end() before being reused as a
     parameter to va_start() or as the dest parameter of a subse-
     quent call to va_copy(). The behavior is undefined if any of
     these restrictions are not met.

     The  va_end() macro is used to clean up. It invalidates pvar
     for use (unless va_start() is invoked again).

     Multiple traversals, each bracketed by a call to  va_start()
     and va_end(), are possible.


EXAMPLES

     Example 1: Creating a Variable Length Command

     The following example uses these routines to create a  vari-
     able length command.  This might be useful for a device that
     provides for a variable-length command set. ncmdbytes is the
     number  of bytes in the command.  The new command is written
     to  cmdp.

     static void
     xx_write_cmd(uchar_t *cmdp, int ncmdbytes, ...)
     {
             va_list     ap;
             int    i;
                 /*
              * Write variable-length command to destination
                  */
              va_start(ap, ncmdbytes);
              for (i = 0; i < ncmdbytes; i++) {
                       *cmdp++ = va_arg(ap, uchar_t);
                  }
              va_end(ap);
     }


SEE ALSO

     vcmn_err(9F), vsprintf(9F)


NOTES

     It is up to the calling routine to specify  in  some  manner
     how  many arguments there are, since it is not always possi-
     ble to determine the number  of  arguments  from  the  stack
     frame.

     Specifying a second argument of char or   short  to   va_arg
     makes  your code non-portable, because arguments seen by the
     called function are not char or short. C converts  char  and
     short arguments to int before passing them to a function.


Man(1) output converted with man2html