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_start
orva_copy
, or ifva_end
is not called before a function that callsva_start
orva_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.
From the MSDN page for va_arg
, va_copy
, va_end
, va_start
:
After all arguments have been retrieved,
va_end
resets the pointer to NULL.va_end
must be called on each argument list that's initialized withva_start
orva_copy
before 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