Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Programming: Forward variable argument list

I'm trying to write a function that accepts a variable number of parameters like printf, does some stuff, then passes the variable list to printf. I'm not sure how to do this, because it seems like it would have to push them onto the stack.

Something approximately like this

http://pastie.org/694844

#include <stdio.h> #include <stdarg.h>  void forward_args( const char *format , ... ){   va_list arglist;   printf( format, arglist ); }   int main (int argc, char const *argv[]){   forward_args( "%s %s\n" , "hello" , "world" );  return 0; } 

Any ideas?

like image 698
Joshua Cheek Avatar asked Nov 12 '09 03:11

Joshua Cheek


People also ask

What is a VA list in C?

va_list is a complete object type suitable for holding the information needed by the macros va_start, va_copy, va_arg, and va_end. If a va_list instance is created, passed to another function, and used via va_arg in that function, then any subsequent use in the calling function should be preceded by a call to va_end.

When can a variable argument list be passed to a function?

If you've converted the variable arguments to a va_list , you can pass the va_list to another function that only takes a va_list , but that function (or one that it calls) must have some way of knowing what's in the va_list .

How do you call a variadic function?

You don't have to do anything special to call a variadic function. Just put the arguments (required arguments, followed by optional ones) inside parentheses, separated by commas, as usual. But you must declare the function with a prototype and know how the argument values are converted.


1 Answers

Don't pass the results to printf. pass them to vprintf. vprintf specifically exists to handle passing in va_list arguments. From the Linux man page:

#include <stdio.h>  int printf(const char *format, ...); int fprintf(FILE *stream, const char *format, ...); int sprintf(char *str, const char *format, ...); int snprintf(char *str, size_t size, const char *format, ...);  #include <stdarg.h>  int vprintf(const char *format, va_list ap); int vfprintf(FILE *stream, const char *format, va_list ap); int vsprintf(char *str, const char *format, va_list ap); int vsnprintf(char *str, size_t size, const char *format, va_list ap); 

Notice how the latter explicitly take va_list arguments such as the ones you declare inside a function taking ... in the parameter list. So your function would be declared like this:

void forward_args( const char *format , ... ){    va_list arglist;    va_start( arglist, format );    vprintf( format, arglist );    va_end( arglist ); } 
like image 66
quark Avatar answered Oct 14 '22 18:10

quark