title: Why is va_arg returning NULL at the end of a variable argument list of type char*?
body: <p>This is what has been said about <code>va_arg</code> in the reputed link below:</p>
  
  <p><a href="http://www.cplusplus.com/reference/cstdarg/va_arg/" rel="nofollow">http://www.cplusplus.com/reference/cstdarg/va_arg/</a></p>
  
  <p><code>Notice also that va_arg does not determine either whether the retrieved argument is the last argument passed to the function (or even if it is an element past the end of that list). The function should be designed in such a way that the number of parameters can be inferred in some way by the values of either the named parameters or the additional arguments already read.</code></p>
  
  <p>In addition to that, in the so-so book from which I read about <code>va_arg</code>,all examples have made sure that one of the <code>fixed</code> arguments is always the number/count of variable arguments we would be passing.And this count is used in a loop that advances <code>va_arg</code> to the next item,and the loop condition (using the count) makes sure that it exits when <code>va_arg</code> retrieves the last argument in the variable list.This seems to corroborate the above paragraph from the site which says that <code>"the function should be designed in such a way........" (above)</code>.</p>
  
  <p>So in blunt words, <code>va_arg</code> is kinda dumb.But in the following example taken from that website for <code>va_end</code>,<code>va_arg</code> suddenly seems to act smartly.When the end of a variable argument list of type <code>char*</code> is reached, it returns a NULL pointer. <strong>How is it so?</strong> The topmost paragraph I linked clearly states</p>
  
  <p><code>"va_arg does not determine either whether the retrieved argument is the last argument passed to the function (or even if it is an element past the end of that list"</code></p>
  
  <p>and further,there is nothing in the following program that ensures that a NULL pointer should be returned when the end of the variable argument list is crossed.So how come <code>va_arg</code> returns a NULL pointer here at the end of the list?</p>
  
  <pre><code>/* va_end example */
  #include &lt;stdio.h&gt;      /* puts */
  #include &lt;stdarg.h&gt;     /* va_list, va_start, va_arg, va_end */
  
  void PrintLines (char* first, ...)
  {
    char* str;
    va_list vl;
  
    str=first;
  
    va_start(vl,first);
  
    do {
      puts(str);
      str=va_arg(vl,char*);
    } while (str!=NULL);
  
    va_end(vl);
  }
  
  int main ()
  {
    PrintLines ("First","Second","Third","Fourth",NULL);
    return 0;
  }    
  </code></pre>
  
  <p><strong>Output</strong> </p>
  
  <pre><code>First
  
  Second
  
  Third
  
  Fourth
  </code></pre>
  
  <p><a href="http://www.cplusplus.com/reference/cstdarg/va_end/" rel="nofollow">Program Source Link</a></p>