va_arg

Syntax:

    #include <cstdarg>
    type va_arg( va_list argptr, type );
    void va_end( va_list argptr );
    void va_start( va_list argptr, last_parm );

The va_arg() macros are used to pass a variable number of arguments to a function.

  1. First, you must have a call to va_start() passing a valid va_list and the mandatory argument that directly precedes the '…' argument of the function. If you only have one mandatory argument, it is that argument. You must have at least one mandatory argument. This argument can be anything; one way to use it is to have it be an integer describing the number of parameters being passed.
  2. Next, you call va_arg() passing the va_list and the type of the argument to be returned. The return value of va_arg() is the current parameter.
  3. Repeat calls to va_arg() for however many arguments you have.
  4. Finally, a call to va_end() passing the va_list is necessary for proper cleanup.

For example:

    int sum( int num, ... ) {
      int answer = 0;
      va_list argptr;
 
      va_start( argptr, num );
 
      for( ; num > 0; num-- ) {
        answer += va_arg( argptr, int );
      }
 
      va_end( argptr );
 
      return( answer );
    }
 
    int main( void ) {
 
      int answer = sum( 4, 4, 3, 2, 1 );
      printf( "The answer is %d\n", answer );
 
      return( 0 );
    }

This code displays 10, which is 4+3+2+1.

Here is another example of variable argument function, which is a simple printing function:

   void my_printf( char *format, ... ) {
     va_list argptr;
 
     va_start( argptr, format );
 
     while( *format != '\0' ) {
       // string
       if( *format == 's' ) {
         char* s = va_arg( argptr, char * );
         printf( "Printing a string: %s\n", s );
       }
       // character
       else if( *format == 'c' ) {
         char c = (char) va_arg( argptr, int );
         printf( "Printing a character: %c\n", c );
         break;
       }
       // integer
       else if( *format == 'd' ) {
         int d = va_arg( argptr, int );
         printf( "Printing an integer: %d\n", d );
       }
 
       format++;
     }
 
     va_end( argptr );
   }
 
   int main( void ) {
 
     my_printf( "sdc", "This is a string", 29, 'X' );
 
     return( 0 );
   }

This code displays the following output when run:

   Printing a string: This is a string
   Printing an integer: 29
   Printing a character: X