I stumbled upon the following code inside mingw_pformat.c. It belongs to the function responsible for handling format specifiers. In particular 'l' and 'L' length modifiers.
case 'l':
# ifndef _WIN32
/*
* Microsoft's MSVCRT implementation also uses `l'
* as a modifier for `long double'; if we don't want
* to support that, we end this case here...
*/
state = PFORMAT_END;
break;
/* otherwise, we simply fall through...
*/
# endif
case 'L':
The if treats "%lf" and "%Lf", this applies to all floating point modifiers as well, as being equal in order to remain compatible with MSVCRT. The problem is that within MSVCRT long double is the same as double.
This results in programs being compiled with __USE_MINGW_ANSI_STDIO to fail when attempting to print a double with "%lf" which is valid when using MSVCRT for the reason above. Applying the included patch produces correct output for common MSVCRT or C99 usage.
#include <stdio.h>
main()
{
double a = 12;
printf("%f %lf\n", a, a);
}
With unmodified mingw_pformat.c
$ gcc promote.c -D__USE_MINGW_ANSI_STDIO && ./a.exe
12.000000 <segfault>
With modified mingw_pformat.c
$ gcc promote.c -D__USE_MINGW_ANSI_STDIO && ./a.exe
12.000000 12.000000
With MSVCRT
$ gcc promote.c && ./a.exe
12.000000 12.000000
mingw_pformat_c.patch
Moved to Patches. https://sourceforge.net/tracker/?func=detail&aid=3474506&group_id=202880&atid=983356