Errata
Errata

Reputation: 640

From parameter pack to var args

Context: I work on legacy code, and while I want to slowly make this code up to c++14 standard, I'm still stuck with function likes printf. Hence this kind of code (simplified):

 #include <iostream>
 #include <string>
 #include <cstdio>

 template <typename... Args>
 const char* Format(const char* strFormat, Args... args)
 {
   static char szBuffer[10000];

   auto len = std::vsnprintf(szBuffer, 10000, strFormat, args...);

   if (len < 0 || 10000 <= len)
   {
     szBuffer[0] = 0;
   }

   return szBuffer;    
 }

 int main()
 {
   auto test = Format("%s %s %d", "test", "test", 42);
 }

This strangely doesn't work : gcc&VS2013 fail to go from expanded parameter pack to va_arg. (http://cpp.sh/4aue)

10:66: error: cannot convert 'const char*' to '__va_list_tag*' for argument '4' to 'int vsnprintf(char*, size_t, const char*, __va_list_tag*)'

Why this behaviour occur ? Meanwhile strangely going for a intermediate var_arg function compile & work correctly (http://cpp.sh/2ggms).

Thank you

Upvotes: 1

Views: 476

Answers (1)

Dark Falcon
Dark Falcon

Reputation: 44191

You want snprintf, not vsnprintf. Parameter packs expand into comma-separated lists. The v version of these functions only accept a va_list.

In looking at your code examples, you're still going to need a function like transform_to_c if you intend to pass a std::string.

Side note: You should consider whether this code needs to be thread-safe or reentrant. Using a static buffer means it is neither.

Upvotes: 3

Related Questions