According to Microsoft's documentation for vsnprintf
, that function is part of the C(++) Run-Time Library since at least the 2003 edition of Visual Studio.
int vsnprintf( char *buffer, // Storage location for output
size_t count, // Maximum number of characters to write
const char *format, // Format specification
va_list argptr ) // Pointer to list of other arguments
I'm asking: for which versions of Visual Studio is the vsnprintf
implementation of the bundled C(++) RTL for x86 and x64 in conformance with the C99 standard (ISO/IEC 9899:1999), assuming
#define _CRT_SECURE_NO_WARNINGS
is performed before #include <stdio.h>
, which is required for modern versions of Visual Studio RTL;count
is greater than zero, then buffer
is a pointer to (at least) count
writable characters;NULL
and conforms to Microsoft's Format Specification syntax as applicable to the particular version of the RTL;count
and the number of characters to produce are both small enough to fit type int
;and we want conformance to include (beside basic functionality for nominal input) these requirements (implied by the standard's specification of snprintf
, which vsnprintf
references):
buffer==NULL
and count==0
, thus allowing pre-flight to determine the length of the output;buffer!=NULL
and count>0
and the result returned is non-negative, including for truncated output due to small count
.Note following comment: I'm willing to admit the lack of restrict
qualifiers as still within allowance for mostly standard-conformant.
The documentation leaves conformance ambiguous with respect to (3.); the implementation bundled with Visual Studio Community 2015 is fine as far as I can tell, but not all are.
If there is room at the end (that is, if the number of characters to write is less than
count
), the buffer will be null-terminated.
The documentation also has wording unambiguously implying that vsnprintf
is not in conformance with the C99 standard with respect to (1.) and (2.) when buffer==NULL
and count==0
; but theses parts of the documentation seemingly turn out to be wrong:
if the number of characters to write is greater than
count
, these functions return -1 indicating that output has been truncated.If
buffer
orformat
isNULL
, or ifcount
is less than or equal to zero, these functions invoke the invalid parameter handler
Test code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdarg.h>
int f( char *buffer,
size_t count,
const char *format,
...
)
{
va_list vArgs;
int vRes;
va_start(vArgs, format);
vRes = vsnprintf( buffer, count, format, vArgs);
va_end(vArgs);
return vRes;
}
int main(void)
{
char vBuf[6];
int j, count;
#ifdef _MSC_VER
printf("_MSC_VER = %ld\n",(long)(_MSC_VER));
#else
printf("_MSC_VER is undefined\n");
#endif
printf("f(NULL,0,\"%%d\",777):%3d\n", f(NULL,0,"%d",777));
for(count=0 ;count<=sizeof(vBuf); ++count)
{
for(j=0; j<sizeof(vBuf)-1; ++j)
vBuf[j] = '!';
vBuf[j] = 0;
j = f(vBuf,count,"%d",777);
printf("f(vBuf,%d,\"%%d\",777):%3d vBuf: \"%s\"\n",count,j,vBuf);
}
return 0;
}
giving under my install of Visual Studio Community 2015
_MSC_VER = 1900
f(NULL,0,"%d",777): 3
f(vBuf,0,"%d",777): 3 vBuf: "!!!!!"
f(vBuf,1,"%d",777): 3 vBuf: ""
f(vBuf,2,"%d",777): 3 vBuf: "7"
f(vBuf,3,"%d",777): 3 vBuf: "77"
f(vBuf,4,"%d",777): 3 vBuf: "777"
f(vBuf,5,"%d",777): 3 vBuf: "777"
f(vBuf,6,"%d",777): 3 vBuf: "777"
and under some install of Visual Studio 2008 (I believe SP1 + PSDK 7.1)
_MSC_VER = 1500
f(NULL,0,"%d",777): 3
f(vBuf,0,"%d",777): -1 vBuf: "!!!!!"
f(vBuf,1,"%d",777): -1 vBuf: "7!!!!"
f(vBuf,2,"%d",777): -1 vBuf: "77!!!"
f(vBuf,3,"%d",777): 3 vBuf: "777!!"
f(vBuf,4,"%d",777): 3 vBuf: "777"
f(vBuf,5,"%d",777): 3 vBuf: "777"
f(vBuf,6,"%d",777): 3 vBuf: "777"
Notice the lack of terminating null character in particular for count==3
, even though the output is positive.
The very page you mention now gives the answer:
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 with older Visual Studio code.
And your output is consistent with _vsnprintf:
Both _vsnprintf and _vsnwprintf functions 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.
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