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