[flac-dev] vsnprintf_s and vsnprintf

Erik de Castro Lopo mle+la at mega-nerd.com
Sat Sep 20 14:11:36 PDT 2014


lvqcl wrote:

> Why? We can use vsnprintf_s for MSVS, and vsnprintf for MinGW.
>
> MSVS version of vsnprintf_s is located inside (statically linked) msvcp???.lib
> or (dynamically linked) msvcp???.dll. They are part of MSVS runtime, and compatible
> with WinXP. So it is safe to use it in FLAC.

Oh, ok. I missed this bit. I know so very little about Windows.

However, if you compile flac on say Win7 using vsnprintf_s and then take
the dynamically compiled binary to WinXP it will fail, right?
 
> As you see, MSVC version of vsnprintf can return positive value
> even when it didn't write '\0' at the end. So
> 	if (rc < 0) { ... str [...] = 0; }
> is not enough.

Like I said, untested. It was the first thing that came into my head version
of the code :-).

> What about this version --
> 
> int flac_snprintf(char *str, size_t size, const char *fmt, ...)
> {
> 	va_list va;
> 	int rc;
> 
> 	va_start (va, fmt);
> 
> #if defined _MSC_VER
> 	rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
> 	if (rc < 0)
> 		rc = size - 1;
> #elif defined __MINGW32__ && (!defined __USE_MINGW_ANSI_STDIO || __USE_MINGW_ANSI_STDIO == 0)
> 	rc = vsnprintf (str, size, fmt, va);
> 	if (rc < 0 || rc == size) {
> 		rc = size - 1;
> 		str [rc] = '\0'; /* assert(size > 0) */
> 	}
> #else
> 	rc = vsnprintf (str, size, fmt, va);
> #endif
> 	va_end (va);
> 
> 	return rc;
> }

I like that but ....

> Or forget about __USE_MINGW_ANSI_STDIO:
> 
> int flac_snprintf(char *str, size_t size, const char *fmt, ...)
> {
> 	va_list va;
> 	int rc;
> 
> 	va_start (va, fmt);
> 
> #if defined _MSC_VER || defined __MINGW32__
> 	rc = vsnprintf (str, size, fmt, va);
> 	if (rc < 0 || rc == size) {
> 		rc = size - 1;
> 		str [rc] = '\0'; /* assert(size > 0) */
> 	}
> #else
> 	rc = vsnprintf (str, size, fmt, va);
> #endif
> 	va_end (va);
> 
> 	return rc;
> }

This one has the advantage of simplicity, there are only two things
to test.

Either of those two are fine. You choose and send a patch. I'll write
a unit test for flac_snprintf to capture our assumptions.

Cheers,
Erik
-- 
----------------------------------------------------------------------
Erik de Castro Lopo
http://www.mega-nerd.com/


More information about the flac-dev mailing list