title: Put a va_list variable inside... a variable argument list (!)
body: <p>I would like to design a function which takes a variable number of arguments, one of these arguments being itself a <code>va_list</code>; but something gets wrong in my code and I do not understand what...</p>
  
  <p><strong>WARNING — My question is not about designing a code doing what I wish to do (I have found a way to bypass the problem), but only about understanding what I did wrong...</strong></p>
  
  <p>To explain my question, let us start with a simple example: namely, a function <code>ffprintf</code> which acts like <code>fprintf</code>, but writing its contents onto several strings, strings whose number is indicated by the first argument of <code>ffprintf</code>, and whose identities are given by the very next arguments (the number of these arguments may vary from one call to another, so you have to use a variable argument list). Such a function would be used like this:</p>
  
  <pre><code>FILE *stream0, *stream1, *stream2;
  int a, b;
  ffprintf (3, stream0, stream1, stream2, "%d divided by %d worths %f", a, b, (double)a / b);
  </code></pre>
  
  <p>And its code would be:</p>
  
  <pre><code>void ffprintf (int z, ...)
   {va_list vlist, auxvlist;
    FILE **streams = malloc (z * sizeof(FILE *));
    va_start (vlist, z);
    for (int i = 0; i &lt; z; ++i)
     {streams[i] = va_arg (vlist, FILE *); // Getting the next stream argument
     }
    char const *format = va_arg (vlist, char const *); // Getting the format argument
    for (int i = 0; i &lt; z; ++i)
     {va_copy (auxvlist, vlist); // You have to work on a copy "auxvlist" of "vlist", for otherwise "vlist" would be altered by the next line
      vfprintf (streams[i], format, auxvlist);
      va_end (auxvlist);
     }
    va_end (vlist);
    free (streams);
   }
  </code></pre>
  
  <p>That works fine. Now, there is also the standard function <code>vfprintf</code>, whose prototype is <code>vfprintf (FILE *stream, char const* format, va_list vlist);</code>, and which you use like this to create another function having a variable argument list:</p>
  
  <pre><code>void fprintf_variant (FILE *stream, char const* format, ...)
   {
    va_list vlist;
    va_start (vlist, format);
    vfprintf (stream, format, vlist);
    va_end (vlist);
   }
  </code></pre>
  
  <p>That works fine too. Now, my goal is to combine both ideas to create a function which I would call <code>vffprintf</code>, which you would use like this:</p>
  
  <pre><code>FILE *stream0, *stream1, *stream2;
  void fprintf_onto_streams012 (char const *format, ...)
   {va_list vlist;
    va_start (vlist, format);
    vffprintf (3, stream0, stream1, stream2, format, vlist);
    va_end (vlist);
   }
  </code></pre>
  
  <p>I have designed the following code:</p>
  
  <pre><code>void vffprintf (int z, ...)
   {va_list vlist, auxvlist, auxauxvlist;
    va_start (vlist, z);
    FILE **streams = malloc (z * sizeof(FILE *));
    for (int i = 0; i &lt; z; ++i)
     {streams[i] = va_arg (vlist, FILE *);
     }
    char const *format = va_arg (vlist, char const *);
    va_copy (auxvlist, va_arg (vlist, va_list)); // Here I get the next argument of "vlist", knowing that this argument is of "va_list" type
    for (int i = 0; i &lt; z; ++i)
     {va_copy (auxauxvlist, auxvlist);
      vfprintf (streams[i], format, auxvlist);
      va_end (auxauxvlist);
     }
    va_end (auxvlist);
    va_end (vlist);
    free (streams);
   }
  </code></pre>
  
  <p>This code compiles without a hitch, but it does not work properly... For instance, if I write the following complete code:</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdarg.h&gt;
  
  void vffprintf (int z, ...)
   {va_list vlist, auxvlist, auxauxvlist;
    FILE **streams = malloc (z * sizeof(FILE *));
    va_start (vlist, z);
    for (int i = 0; i &lt; z; ++i)
     {streams[i] = va_arg (vlist, FILE *);
     }
    char const *format = va_arg (vlist, char const *);
    va_copy (auxvlist, va_arg (vlist, va_list));
    for (int i = 0; i &lt; z; ++i)
     {va_copy (auxauxvlist, auxvlist);
      vfprintf (streams[i], format, auxauxvlist);
      va_end (auxauxvlist);
     }
    va_end (auxvlist);
    va_end (vlist);
    free (streams);
   }
  
  void printf_variant (char const *format, ...)
   {va_list vlist;
    va_start (vlist, format);
    vffprintf (1, stdout, format, vlist);
    va_end (vlist);
   }
  
  int main (void)
   {printf_variant ("Ramanujan's number is %d.\n", 1729);
    return 0;
   }
  </code></pre>
  
  <p>I get a segfault!... Why?!</p>
  
  <p>P.-S.: Sorry for that very long question; but I wanted it to be perfectly clear, for it is rather technical...</p>
  
  <p>P.-S.2: I used deliberately both tags "va-list" and "variableargumentlists" for this question, because which interests me is <code>va_list</code>, <em>seen as a type</em>, inside a (other) variable argument list, <em>seen as a list</em>... So these are really two different concepts here.</p>