MinGW doesn't produce warnings
I have successfully installed MinGW on a Windows 7 32bit machine, and have tried to compile a simple program using either the command line or the MinGW console.
The code has an intentional error in a printf statement:
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
printf("%dn" , 3.14 ) ;
return 0 ;
}
The command gcc -Wall hello.c
gives a correct warning: hello.c:7:2: warning: format '%d' expects argument of type 'int'...
But the command gcc -std=c99 -Wall hello.c
doesn't give any warning.
Both create an executable a.exe ( that runs and gives the same result ).
(Interestingly a command gcc -std=gnu99 -Wall hello.c
gives the warning.)
I don't know if this is a bug, or did the installation go wrong somehow, but both seem unlikely since the compiler works and successfully compiled a larger project( but the same warning of course omitted when using -std=c99 ).
I must be missing some information.
(ps: If someone has a new MinGW install, please test this.)
gcc version 4.8.1 (GCC)
Update 1:
Defining _GNU_SOURCE
before including stdio.h
removes the warning even with gcc -Wall hello.c
.
Update 2( might be less relevant ):
Compiling
printf("%lfn" , 3.14 ) ;
-std=c99
flag outputs: 0.000000
-std=gnu99
outputs: 3.140000
And compiling:
printf("%fn" , 3.14 ) ;
-std=gnu99
and -std=c99
output: 3.140000
Update 3:
Functions that seem to be affected are: printf, fprintf, snprintf, sprintf.
The problem with the lack of warning when using the std=c99
option looks like it's because MinGW 4.8.1 preprocesses stdio.h
a little different for the printf()
family of functions when -std=c99
is used compared to when -std=gnu99
is used.
Note: I'm looking at MinGW 4.8.1 from TDM - I think other distributions might differ in these details.
MinGW has had some compatibility issues with formatting floating point values because of its historic reliance on msvcrt.dll
for the C runtime and the fact that MSVC uses a 64-bit representation for long double
while gcc uses a 96-bit (or 128-bit on x64) representation. See gcc: printf and long double leads to wrong output. [C - Type conversion messes up] for some details. More recent versions of MinGW have provided thier own implementation of the printf()
family of functions (with a __mingw_
prefix on the name) in libmingwex.a
to solve those problems.
The header files _mingw.h
and stdio.h
configure whether or not the libmingwex.a
implementations or the msvcrt.dll
implementations will be used.
It appears that if ANSI compliance is requested, MinGW will use the libmingwex.a
implementations (there are a number of other ways to get this configuration too - look at the headers for details). Wiring up a user call to printf()
to the __mingw_printf()
implementation in libmingwex.a
is done by stdio.h
defining a static inline implementation of printf()
that is a thin wrapper around a call to __mingw_vfprintf()
. Apparently the -Wformat
doesn't get applied to versions of printf()
family functions that the compiler doesn't believe to be part of the library (a reasonable assumption - the compiler doesn't really know anything about those functions). This problem can be fixed by applying the appropriate function attribute (for example: __attribute__ ((format (printf, 1, 2)))
) to the static inline wrapper functions.
The other problem you found, where printf("%lfn", 3.14)
prints 0.000000
when using std=c99
, looks to be a bug in the libmingwex.a
implementation of __mingw_vfprintf()
. It seems that __mingw_vfprintf()
mistakenly interprets "%lf"
to mean the argument is a long double
. I'm not too surprised by that - I always have to look up whether %lf
means double
or long double
.
上一篇: MSVCRT系统函数返回码始终为
下一篇: MinGW不会产生警告