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...
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_startorva_copy, or ifva_endis not called before a function that callsva_startorva_copyreturns, 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.
From the MSDN page for va_arg, va_copy, va_end, va_start:
After all arguments have been retrieved,
va_endresets the pointer to NULL.va_endmust be called on each argument list that's initialized withva_startorva_copybefore the function returns.
So yes, this is a documentation bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With