Hi, Alternatively, you can compile the program with -D__USE_MINGW_ANSI_STDIO :
C:\_32\C>type try.c /* try.c */ #include <stdio.h> int main() { char buf[5] = "XXXX"; int ret = snprintf(buf, 3, "%d", 123456789); printf("buf=%s ret=%d\n", buf, ret); return 0; } C:\_32\C>gcc -o try.exe try.c -D__USE_MINGW_ANSI_STDIO C:\_32\C>try buf=12 ret=9 C:\_32\C> On Fri, May 10, 2019 at 11:09 PM Pali Rohár <pali.ro...@gmail.com> wrote: > Hello! > > snprintf() function in mingw-w64 is broken. Seems that it just calls > MSVC's _snprintf() function which is not same as snprintf(). MSVC until > ucrt does not provide snprintf() at all, just _snprintf(). > > Differences are that MSVC's _snrpintf() does not ensure that filled > buffer would be null-termed and when overflow occurs it returns -1 > instead of length which is needed to fully format string. > > See following example: > > #include <stdio.h> > > int main() { > char buf[5] = "XXXX"; > int ret = snprintf(buf, 3, "%d", 123456789); > printf("buf=%s ret=%d\n", buf, ret); > return 0; > } > > It prints: > > buf=123X ret=-1 > > So for MSVC's _snprintf() it is needed to write wrapper, e.g. following: > > #define snprintf(str, size, format, ...) ( (((size_t)(size) > 0) ? > (_snprintf((str), (size), (format), __VA_ARGS__), ((char > *)str)[(size_t)(size)-1] = 0, 0) : 0), _scprintf((format), __VA_ARGS__) ) > > It is simple inline-able macro so it does not increase executable code > size too much. > > MSVC's _scprintf() function returns length of formatted string, so > exactly what snprintf() return value should be. > > With that snprintf() define, output of above example is: > > buf=12 ret=9 > > Which is correct now. > > Would you consider fixing snprintf() in mingw-w64? > > Similarly also vsnprintf() can be fixed: > > #define vsnprintf(str, size, format, ap) ( (((size_t)(size) > 0) ? > (_vsnprintf((str), (size), (format), (ap)), ((char *)str)[(size_t)(size)-1] > = 0, 0) : 0), _vscprintf((format), (ap)) ) > > -- > Pali Rohár > pali.ro...@gmail.com > _______________________________________________ > Mingw-w64-public mailing list > Mingw-w64-public@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/mingw-w64-public > _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public