va_copy 如何 移植到Visual C ++?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (207)

我的方法显示了打印到字符串的一种很好的方式。答案涉及va_copy:

std::string format (const char *fmt, ...);
{
   va_list ap;
   va_start (ap, fmt);
   std::string buf = vformat (fmt, ap);
   va_end (ap);
   return buf;
}


std::string vformat (const char *fmt, va_list ap)
{
   // Allocate a buffer on the stack that's big enough for us almost
   // all the time.
   s ize_t size = 1024;
   char buf[size];

   // Try to vsnprintf into our buffer.
   va_list apcopy;
   va_copy (apcopy, ap);
   int needed = vsnprintf (&buf[0], size, fmt, ap);

   if (needed <= size) {
       // It fit fine the first time, we're done.
       return std::string (&buf[0]);
   } else {
       // vsnprintf reported that it wanted to write more characters
       // than we allotted.  So do a malloc of the right size and try again.
       // This doesn't happen very often if we chose our initial size
       // well.
       std::vector <char> buf;
       size = needed;
       buf.resize (size);
       needed = vsnprintf (&buf[0], size, fmt, apcopy);
       return std::string (&buf[0]);
   }

}

我遇到的问题是上面的代码没有连接到Visual C ++,因为它不提供va_copy(甚至是__va_copy)。那么,有没有人知道如何安全地移植上述代码?据推测,我需要做一个va_copy副本,因为vsnprintf破坏性地修改了传递的va_list。

提问于
用户回答回答于

你应该能够摆脱常规任务:

va_list apcopy = ap;

这在技术上是不可移植和未定义的行为,但它可以与大多数编译器和体系结构一起使用。在x86调用约定中,va_lists只是指向堆栈的指针,并且可以安全地进行复制。

用户回答回答于

对于Windows,你可以简单地自定义va_copy:

#define va_copy(dest, src) (dest = src)

扫码关注云+社区

领取腾讯云代金券