title: va_args and 64 bits
body: <p>I'm the lead dev for <a href="http://bitfighter.org" rel="nofollow noreferrer">Bitfighter</a>, and am having problems porting the game to 64-bit Linux.  This should be a relatively easy and common problem, but it has stumped a number of people and I have been able to find no good information about it.</p>
  
  <p>[[ The code compiles in 32-bit with gcc version 4.1.2, and others, and fails with several variants of 64-bit Linux, but I am relying on reports from others, and do not have the exact version of gcc that is failing.  But it is failing for several people, on a variety of Linux flavors.  I am 99% sure this is not a compiler version issue. ]]</p>
  
  <p>I have the following:</p>
  
  <pre><code> void UserInterface::drawCenteredString(int y, int size, const char *format, ...)
     {
      va_list args; 
      va_start(args, format); 
      char buffer[2048]; 
      dVsprintf(buffer, sizeof(buffer), format, args); 
      va_end(args);
  
      drawCenteredString2(y, size, buffer);
   }   
  
   // Elsewhere, in platform.cpp... (this is where the error occurs)
  
   S32 dVsprintf(char *buffer, int bufferSize, const char *format, void *arglist)
   {
      return vsnprintf(buffer, bufferSize, format, (char *) arglist);
   }
  </code></pre>
  
  <p>This works great on 32-bit platforms.  However, when I compile it on 64-bit Linux, it fails:</p>
  
  <pre><code> platform.cpp:457: error: cannot convert 'char*' to '__va_list_tag*' for argument '4' to 'int TNL::vsnprintf(char*, size_t, const char*, __va_list_tag*)'
  </code></pre>
  
  <p>I've tried many variants, including: </p>
  
  <pre><code>return vsnprintf(buffer, bufferSize, format, (va_list) arglist);
  </code></pre>
  
  <p>without success.   </p>
  
  <p>Does anyone have any ideas on how to make this construct portable, or achieve the same ends with a more 64-bit friendly mechanism?</p>
  
  <p>And, for bonus points :-) can anyone tell me where the va_list_tag thingy comes from?</p>
  
  <p>Thanks!</p>
  
  <p>============================================</p>
  
  <p>Here is the solution we settled on, using a different example:</p>
  
  <pre><code>logprintf("Hello %s", name);
  </code></pre>
  
  <p>calls</p>
  
  <pre><code>void logprintf(const char *format, ...)
  {
     va_list s;    
     va_start( s, format );
  
     logger(LogConsumer::GeneralFilter, format, s);
     va_end(s);
  }
  </code></pre>
  
  <p>calls</p>
  
  <pre><code>void logger(LogConsumer::FilterType filtertype, const char *format, va_list args)
  {
     char buffer[4096];
  
     vsnprintf(buffer, sizeof(buffer), format, args);
  
     Platform::outputDebugString(buffer);
  }
  </code></pre>