如何从gcc关闭错误的浮点/长错误消息

时间:2009-04-14 21:25:11

标签: c gcc gcc-warning

我最近对某些变量从float到long的代码库进行了更改,并发现编译器在我知道仍然错误的区域中没有生成错误消息。这导致我将-Wconversion添加到编译器标志。但是,oops,这会导致一些虚假的错误消息。在下面的代码段中,我收到了错误,如上所述。我可以做些什么来根据具体情况来抑制这个消息,或者让gcc变得更聪明? -Wconversion标志在我们的代码库中生成数千个警告。我是否必须全部检查它们?哎呀。

#include <stdio.h>
void
takes_a_float  ( float some_num ) {
    printf("float Hello %f\n", some_num );
}
int
main (int argc, char **argv)  {
    float my_boat = 1.0f;
    takes_a_float (  my_boat );
    exit (0);
}

gcc -Wconversion foo.c
foo.c: In function `main':
foo.c:13: warning: passing arg 1 of `takes_a_float' as `float' rather than `double' due to prototype

 $ gcc -v
Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr   /share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=x86_64-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-10)

修改

正如John Millikin指出的那样,-Wconversion标志正在“按设计”工作。 (我以为它是关于类型转换的,但事实证明它是关于将真正旧的C风格程序转换为ISO标准C.Darn。阅读gcc警告 我的gcc版本的文档页面并没有给我带来希望,但无论如何,我真正想要的是其他一些警告标志,它将在下面的代码中正确警告,而不是给出虚假的警告。

#include <stdio.h>
#include <stdlib.h>


void
takes_a_long  ( long sad_story ) {
    printf("Long %lu\n", sad_story );
}

void
takes_a_float  ( float my_boat ) {
    printf("Float  %f\n", my_boat );
}

int
main (int argc, char **argv)  {

    float   my_boat     = 1.0f;
    long    sad_story   = 1.0L;

    // No warnings wanted
    takes_a_float (my_boat);
    takes_a_long (sad_story);

    // Warnings required
    takes_a_long  (my_boat);
    takes_a_float (sad_story);

    exit (0);
}

修改2

真正的解决方案是升级我的编译器。由于复杂的原因(叹息),公司不愿意这样做。

4 个答案:

答案 0 :(得分:3)

来自manpage(也在http://lists.apple.com/archives/xcode-users/2008/Jul/msg00720.html):

  

<强> -Wconversion

     

如果原型导致类型转换,则发出警告   会发生什么不同   没有a的相​​同论点   原型。这包括转化   固定点浮动和副   反之亦然,改变了转换   固定点的宽度或符号   参数除了与之相同时   默认促销。

因此,警告的执行完全符合记录。如果您想专门检查某些转化,可以尝试在一次运行中启用-Wconversion,将其记录到文件中,然后搜索long - &gt;转化float


此选项显然是用于将传统C移植到ISO / ANSI C。

答案 1 :(得分:2)

从信息页面猜测,您是否尝试-Wno-traditional-conversion

编辑:我检查过,但它很有效,但遗憾的是,这适用于gcc 4.3和更新版本。从gcc 4.1手册页看来,您观察到的行为似乎是-Wconversion在旧版本中应该执行的操作,并且它不会对正常double -> float转换发出警告。

答案 2 :(得分:2)

我相信您最有可能寻找的旗帜是 -Wall ,您可能希望与 -std=XX 结合使用,其中XX是其中之一(c89 | gnu89 | c99 | gnu99 | ...),和/或可能 -pedantic ,这更令人讨厌迂腐(或者根据你的心情保持更多* lly保持:)< / p> 顺便说一下,你忘了包含stdlib.h(对于exit()原型。


#include <stdio.h>
#include <stdlib.h>

void takes_a_float ( float some_num ) {
    printf("float Hello %f\n", some_num );
}

int main (int argc, char **argv)  {
   float my_boat = 1.0;
   takes_a_float (  my_boat );
   exit( 0 );
}

和我的控制台输出:


mctaylor@tigger:stackoverflow$ gcc -Wall -pedantic long_float.c -o long_float
mctaylor@tigger:stackoverflow$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
...
gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu12) 

使用 -Wall -pedantic 强制您编写干净,明确的代码,并可以帮助您捕获许多潜在的愚蠢错误。祝你好运。

我想知道“缺少警告”消息是否可能是因为C类型促销规则。 (参见K&amp; R The C Programming Language,2nd ed,section 2.7 - Type Conversion )。只是值得深思。

我希望这会有所帮助。

已编辑以添加其他材料(紧随其后):

另一个选项或方法是splint(安全编程Lint)或Gimple Software的PC-lint / FlexLint,这是lint实现静态分析C源代码的标记< em>可疑和不可移植的构造。


mctaylor@tigger:stackoverflow$ splint sad_story.c 
Splint 3.1.2 --- 07 May 2008

sad_story.c: (in function takes_a_long)
sad_story.c:5:26: Format argument 1 to printf (%lu) expects unsigned long int
                     gets long int: sad_story
  To ignore signs in type comparisons use +ignoresigns
   sad_story.c:5:20: Corresponding format code
sad_story.c: (in function main)
sad_story.c:21:18: Function takes_a_long expects arg 1 to be long int gets
                      float: my_boat
  To allow all numeric types to match, use +relaxtypes.
sad_story.c:22:19: Function takes_a_float expects arg 1 to be float gets long
                      int: sad_story
sad_story.c:12:15: Parameter argc not used
  A function parameter is not used in the body of the function. If the argument
  is needed for type compatibility or future plans, use /*@unused@*/ in the
  argument declaration. (Use -paramuse to inhibit warning)
sad_story.c:12:28: Parameter argv not used
sad_story.c:4:6: Function exported but not used outside sad_story: takes_a_long
  A declaration is exported, but not used outside this module. Declaration can
  use static qualifier. (Use -exportlocal to inhibit warning)
   sad_story.c:6:1: Definition of takes_a_long
sad_story.c:8:6: Function exported but not used outside sad_story:
                    takes_a_float
   sad_story.c:10:1: Definition of takes_a_float

Finished checking --- 7 code warnings

您也可以在Gimpel Online Testing的FlexLint中尝试这个示例,它更清晰,更漂亮。

答案 3 :(得分:0)

我没有得到这个警告,我想这是因为我使用的是更新版本的GCC(4.3.3)。