MinGW不会发出警告

时间:2014-12-08 17:49:10

标签: c windows gcc mingw

我已经在Windows 7 32位机器上成功安装了MinGW,并尝试使用命令行或MinGW控制台编译一个简单的程序。

代码在printf语句中有故意错误:

#include <stdio.h>
#include <stdlib.h>
int main( void )
{
    printf("%d\n" , 3.14 ) ;
return 0 ;
}

命令gcc -Wall hello.c给出正确的警告: hello.c:7:2:警告:格式'%d'需要类型'int'的参数...

但命令gcc -std=c99 -Wall hello.c没有发出任何警告。

两者都创建一个可执行文件 a.exe (运行并提供相同的结果)。

(有趣的是,命令gcc -std=gnu99 -Wall hello.c会发出警告。)

我不知道这是不是一个bug,或者安装是否出错了,但是由于编译器工作并成功编译了一个更大的项目,所以两者似乎都不太可能(但是当使用-std = c99时,当然会忽略相同的警告)。

我一定错过了一些信息。

(ps:如果有人安装了新的MinGW,请测试一下。)

gcc版本4.8.1(GCC)

更新1:

在包含_GNU_SOURCE之前定义stdio.h即使gcc -Wall hello.c也会删除警告。

更新2(可能不太相关):

编译

 printf("%lf\n" , 3.14 ) ;

-std=c99标志输出:0.000000

-std=gnu99输出:3.140000

编译:

 printf("%f\n" , 3.14 ) ;

-std=gnu99-std=c99输出:3.140000

更新3:

似乎受影响的函数有:printf,fprintf,snprintf,sprintf。

1 个答案:

答案 0 :(得分:15)

使用std=c99选项时缺少警告的问题看起来像是因为当{{1}时,MinGW 4.8.1预处理stdio.h对于printf()函数系列略有不同与使用-std=c99时相比使用。

注意:我正在从TDM看MinGW 4.8.1 - 我认为其他发行版可能在这些细节上有所不同。

MinGW在格式化浮点值方面存在一些兼容性问题,因为它对C运行时的历史依赖-std=gnu99以及MSVC对msvcrt.dll使用64位表示的事实,而gcc使用了96位(或x64上的128位)表示。有关详细信息,请参阅gcc: printf and long double leads to wrong output. [C - Type conversion messes up]。更新版本的MinGW已经在long double中提供了printf()函数系列(名称上带有__mingw_前缀)的自己实现,以解决这些问题。

标头文件libmingwex.a_mingw.h配置是否将使用stdio.h实施或libmingwex.a实施。

似乎如果要求ANSI合规性,MinGW将使用msvcrt.dll实现(还有许多其他方法来获取此配置 - 请查看标题以获取详细信息)。将用户调用libmingwex.aprintf()中的__mingw_printf()实现联系,由libmingwex.a定义stdio.h的静态内联实现,这是一个很薄的包装器致电printf()。显然__mingw_vfprintf()没有应用于编译器认为不属于库的-Wformat族函数版本(一个合理的假设 - 编译器对这些函数一无所知)功能)。通过将适当的函数属性(例如:printf())应用于静态内联包装函数,可以解决此问题。

您在使用__attribute__ ((format (printf, 1, 2)))printf("%lf\n", 3.14)打印0.000000时发现的另一个问题,似乎是std=c99 libmingwex.a实施中的错误。似乎__mingw_vfprintf()错误地解释__mingw_vfprintf()意味着论证是"%lf"。我对此并不感到惊讶 - 我总是要查找long double%lf还是double