vsnprintf_s呼叫后va_end需要

Is va_end required after a vsnprintf_s call?

本文关键字:end 需要 va 呼叫 vsnprintf      更新时间:2023-10-16

MSDN 显示了vsnprintf_s以下示例代码片段:

// crt_vsnprintf_s.cpp
#include <stdio.h>
#include <wtypes.h>
void FormatOutput(LPCSTR formatstring, ...) 
{
   int nSize = 0;
   char buff[10];
   memset(buff, 0, sizeof(buff));
   va_list args;
   va_start(args, formatstring);
   nSize = vsnprintf_s( buff, _countof(buff), _TRUNCATE, formatstring, args);
   printf("nSize: %d, buff: %sn", nSize, buff);
}
int main() {
   FormatOutput("%s %s", "Hi", "there");
   FormatOutput("%s %s", "Hi", "there!");
   FormatOutput("%s %s", "Hi", "there!!");
}

在此示例中,调用va_start时没有匹配的va_end

这是 MSDN 中的文档错误,还是我们应该在调用vsnprintf_s之前调用va_start,然后让此函数为我们进行清理(即调用 va_end (?

顺便说一句:我尝试了上面的代码,它适用于带有更新 2015 的 VS3,但我不知道它是否只是未定义的行为......

需要

为每个va_start调用va_end。从 http://en.cppreference.com/w/c/variadic/va_end:

如果没有对 va_startva_copy 的相应调用,或者在调用 va_startva_copy 返回的函数之前未调用va_end,则行为是未定义的。

您不仅需要va_end还需要确保在执行va_end之前不会返回函数,如果执行va_startva_copy

回答您的问题 - 是的,这是 MSDN 中的一个文档错误。

从 MSDN 页面的 va_argva_copyva_endva_start

检索完所有参数后,va_end将指针重置为 零。 必须在初始化的每个参数列表上调用va_end 在函数返回之前va_startva_copy

所以是的,这是一个文档错误。

假设vsnprintf_s应该类似于vsnprintf,那么你不应该期望它为你调用va_end()

函数vprintf()vfprintf()vdprintf()vsprintf()vsnprintf()分别等价于函数printf()fprintf()dprintf()sprintf()snprintf(),只是它们被调用时带有 va_list而不是可变数量的参数。 这些函数不调用va_end宏。 由于它们调用va_arg宏,因此在调用后未定义ap的值。 请参阅stdarg(3)

(我的强调(