If you use variable arguments ( va_list either from or ), you need to be careful to "recycle" your va_list object if you intend to reuse it.

Thus, instead of:

  void fun(char *format, ...) {
    va_list args;
 
    va_start(args, format);
    vprintf(format, args);
    vfprintf(stderr, format, args);
    va_end(args);
  }

You need to use:

 void fun(char *format, ...) {
    va_list args;
 
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
  }

Obviously, this example is using -style variable arguments but the same is true for : you must recycle your va_list if you reuse it. This is compliant with the ANSI C standard (section 4.8):

The (va_list) object "ap" may be passed as an argument to another function; if that function invokes the "va_arg" macro with parameter "ap", the value of "ap" in the calling function is indeterminate and shall be passed to the "va_end" macro prior to any further reference to "ap".

The wrong way

Here is an example showing the wrong way to reuse your va_list object:

 $ cat stdargs.c
  #include 
  #include 
 
  void fun(char *format, ...) {
    va_list args;
 
    va_start(args, format);
    vprintf(format, args);
    vfprintf(stderr, format, args);
    va_end(args);
  }
 
  main() {
    fun("

 

Contact IBM

Browse z/OS