简体   繁体   中英

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("%d\n" , 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("%lf\n" , 3.14 ) ;

-std=c99 flag outputs: 0.000000

-std=gnu99 outputs: 3.140000

And compiling:

 printf("%f\n" , 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("%lf\\n", 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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM