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

Reply via email to