Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MinGW doesn't produce warnings

Tags:

c

windows

gcc

mingw

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.

like image 385
2501 Avatar asked Dec 08 '14 17:12

2501


People also ask

Is MinGW discontinued?

Mingw.org obviously isn't completely dead, but the latest version there is gcc 4.5.

Is MinGW-w64 a virus?

The other one is MinGW-w64, which was available for download at the beginning of our investigation. It contains several malicious payloads including a bitcoin stealer and a virus. MinGW is basically a port of GCC (GNU Compiler Collection) for Microsoft Windows.

Is MinGW deprecated?

org's MinGW, sadly, is no longer regarded as the main MS-Windows target by free software developers. > >

Is MinGW-w64 better than MinGW?

If your program will run only on Windows, then MinGW is likely the better choice. MinGW is designed to create Windows applications. It doesn't require users to install additional software to run your application.


1 Answers

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.

like image 199
Michael Burr Avatar answered Oct 17 '22 02:10

Michael Burr