Mr.C64 Mr.C64 - 1 month ago 16
C Question

Is va_end required after a vsnprintf_s call?

MSDN shows this sample code snippet for

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: %s\n", nSize, buff);
}

int main() {
FormatOutput("%s %s", "Hi", "there");
FormatOutput("%s %s", "Hi", "there!");
FormatOutput("%s %s", "Hi", "there!!");
}



In this sample,
va_start
is called without a matching
va_end
.

Is this a doc bug in MSDN, or should we just call
va_start
before invoking
vsnprintf_s
and then let this function do the cleanup (i.e. calling
va_end
) for us?

BTW: I tried the above code and it works with VS2015 with Update 3, but I don't know if it's just undefined behavior...

Answer

va_end needs to be called for every va_start. From http://en.cppreference.com/w/c/variadic/va_end:

If there is no corresponding call to va_start or va_copy, or if va_end is not called before a function that calls va_start or va_copy returns, the behavior is undefined.

Not only do you need va_end but you also need to make sure that your function does not return before va_end is executed if va_start or va_copy is executed.

To answer your question - yes, this is a documentation bug in MSDN.