The C99 standard says:
§7.19.6.12 The vsnprintf
function
#include <stdarg.h>
#include <stdio.h>
int vsprintf(char *restrict s, size_t n, const char *restrict format, va_list arg);
Description
¶2 The vsnprintf
function is equivalent to snprintf
, with the variable argument list
replaced by arg
, which shall have been initialized by the va_start
macro (and
possibly subsequent va_arg
calls). The vsnprintf
function does not invoke the
va_end
macro.245) If copying takes place between objects that overlap, the behavior is
undefined.
Returns
¶3 The vsnprintf
function returns the number of characters that would have been written
had n
been sufficiently large, not counting the terminating null character, or a negative
value if an encoding error occurred. Thus, the null-terminated output has been
completely written if and only if the returned value is nonnegative and less than n
.
245) As the functions vfprintf
, vfscanf
, vprintf
, vscanf
, vsnprintf
, vsprintf
, and
vsscanf
invoke the va_arg
macro, the value of arg
after the return is indeterminate.
And, since it is defined in terms of snprintf()
, here's that section:
§7.19.6.5 The snprintf
function
#include <stdio.h>
int snprintf(char *restrict s, size_t n, const char *restrict format, ...);
Description
¶2 The snprintf
function is equivalent to fprintf
, except that the output is written into
an array (specified by argument s
) rather than to a stream. If n
is zero, nothing is written,
and s
may be a null pointer. Otherwise, output characters beyond the n
-1st are
discarded rather than being written to the array, and a null character is written at the end
of the characters actually written into the array. If copying takes place between objects
that overlap, the behavior is undefined.
Returns
¶3 The snprintf
function returns the number of characters that would have been written
had n
been sufficiently large, not counting the terminating null character, or a negative
value if an encoding error occurred. Thus, the null-terminated output has been
completely written if and only if the returned value is nonnegative and less than n
.
It doesn't say it will return -1
on an error; just any negative value. So yes, it is allowed to give a negative value with a magnitude greater than 1 on an error.
Microsoft's Versions
Note that Microsoft's specification for vsnprintf
for Visual Studio 2015 says:
vsnprintf
returns the number of characters written, not counting the terminating null character. A return value of -1 indicates that an encoding error has occurred. If the buffer size specified by count is not sufficiently large to contain the output specified by format and argptr, the return value of vsnprintf is the number of characters that would be written if count were sufficiently large. If the return value is greater than count - 1, the output has been truncated.
Both _vsnprintf
and _vsnwprintf
return the number of characters written if the number of characters to write is less than or equal to count; if the number of characters to write is greater than count, these functions return -1 indicating that output has been truncated. The return value for all functions does not include the terminating null, if one is written.
Note that this was not always the case:
Beginning with the UCRT in Visual Studio 2015 and Windows 10, vsnprintf
is no longer identical to _vsnprintf
. The vsnprintf
function complies with the C99 standard; _vnsprintf
is retained for backward compatibility.
For comparison, the Visual Studio 2013 documentation says:
vsnprintf
, _vsnprintf
, and _vsnwprintf
return the number of characters written if the number of characters to write is less than or equal to count; if the number of characters to write is greater than count, these functions return -1 indicating that output has been truncated. The return value does not include the terminating null, if one is written.
The comparable pages for snprintf()
are: