Hi,

I'm new here, so please be gentle :)
For an application I'm working on I need to implement a callback function that takes a va_list as an argument. Inside that function, however, I need to pass the va_list (or rather all arguments of the callback function) to a function with a printf-like syntax (i.e. not a va_list). I was thus wondering if there's a way to "convert" a va_list so that it can be used with a printf-like function. Obviously, I could use vsprintf to write everything into one string first, but that would require quite a large buffer. Is there another way to do it?

Thanks,
Alex

>I was thus wondering if there's a way to "convert" a
>va_list so that it can be used with a printf-like function.
No, a variable argument list and a va_list object are directly equivalent to an object of type T and a pointer to type T, respectively. The types are incompatible, and while you can convert an object of type T into a pointer to type T using the & operator (or a variable argument list to a va_list object using the va_start macro), you can't assign a pointer to type T to an object of type T (or a va_list object to a variable argument list). Because of that, while this may compile, the behavior is undefined (where "undefined" in this case usually means it's not going to work):

#include <stdio.h>
#include <stdarg.h>

void foo ( int n, ... );
void bar ( int n, va_list args );
void baz ( int n, ... );

int main ( void )
{
  foo ( 4, "this", "is", "a", "test" );
  return 0;
}

void foo ( int n, ... )
{
  va_list args;

  va_start ( args, n );
  bar ( n, args );
  va_end ( args );
}

void bar ( int n, va_list args )
{
  baz ( n, args );
}

void baz ( int n, ... )
{
  va_list args;

  va_start ( args, n );
  while ( --n >= 0 )
    printf ( "%s\n", va_arg ( args, char* ) );
  va_end ( args );
}

If you have the power to do so, the best solution is the one that the standard library uses. For each variadic function, supply a corresponding function that takes a va_list. That's a trivial solution because there's no repetition (the variadic function can be implemented in terms of the va_list function), but it does require that the va_list function do all of the work. For example, here's a reasonable implementation of printf and vprintf:

int printf ( const char *fmt, ... )
{
  va_list args;
  int rv;

  va_start ( args, fmt );
  rv = vprintf ( fmt, args );
  va_end ( args );

  return rv;
}

int vprintf ( const char *fmt, va_list args )
{
  return _print_stream ( stdout, fmt, args );
}

vprintf is doing all of the work while printf is deferring to vprintf.

This article has been dead for over six months. Start a new discussion instead.