在不使用va_copy的情况下将va_list传递给另一个函数是否安全?

时间:2014-11-16 03:03:53

标签: c language-lawyer c99 variadic-functions

This blog post声称将va_list传递给另一个函数(如下面的代码中)是不安全的,并且必须首先使用va_list复制va_copy

void
foo_ap(const char *fmt, va_list ap)
{
    char buf[128];

    vsnprintf(buf, sizeof(buf), fmt, ap);

    // now, do something with buf ...
}

就像博客文章提到的评论之一一样,我无法看到这是不安全的,正如C99规范所述(7.15):

  

对象ap可以作为参数传递给另一个函数;如果该函数调用带有参数va_arg的{​​{1}}宏,则调用函数中ap的值是不确定的,并且在进一步引用之前应传递给ap宏到va_end

(只要ap在传递之后没有引用foo_ap,句子的第二部分似乎无论如何都不适用。)博客的作者帖子在另一条评论中说他可能错了,但也许有人可以补充一些说明。我真的必须使用ap才能安全吗?或者是否有任何平台不符合规范并需要使用va_copy

1 个答案:

答案 0 :(得分:8)

如果您仍然计划在va_copy返回后使用ap,则只需vsnprintf。例如,您可能希望两次调用vsnprintf - 一次确定所需的缓冲区大小,然后再次格式化为real。如果您不需要再次使用ap(除非将其传递给va_end,如果您是使用va_start创建它的人),那么您不需要{ {1}}它。