代码之家  ›  专栏  ›  技术社区  ›  Leonard

如何关闭来自gcc的错误float/long错误消息

  •  2
  • Leonard  · 技术社区  · 16 年前

    最近,我对一些变量对代码库进行了从float改为long的更改,发现编译器在我知道仍然是错误的地方没有生成错误消息。这导致我将-wconversion添加到编译器标志中。但是,糟糕的是,这会导致一些虚假的错误消息。在下面的代码片段中,我得到了错误。我该怎么做才能根据具体情况抑制这条消息,或者诱使GCC更明智地处理这一问题?-wconversion标志在我们的代码库中生成数千个警告。我要检查一下吗?GRRR

    #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)
    

    编辑

    正如JohnMillikin指出的那样,-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 回复  |  直到 16 年前
        1
  •  2
  •   jpalecek    16 年前

    只是从信息页面猜测一下,你试过了吗? -Wno-traditional-conversion ?

    编辑:我检查过了,它工作了,但是很遗憾,这只适用于GCC4.3和更新版本。从GCC4.1手册页,你观察到的行为似乎是 -Wconversion 在旧版本中应该这样做,但在正常情况下不发出警告 double -> float 转换。

        2
  •  3
  •   John Millikin    16 年前

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

    -转换

    如果原型导致的类型转换是 不同于会发生什么 在没有 原型。这包括转换 固定点对浮动和虎钳 反之亦然,转换将更改 固定点的宽度或印痕 参数,除非与 默认提升。

    因此,警告的执行与记录的完全一致。如果您想专门检查一些转换,可以尝试打开 -Wconversion 在一次运行中,将其记录到一个文件中,然后搜索 long -gt; float 转换。


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

        3
  •  2
  •   mctylr    16 年前

    我相信你最可能要找的旗子是 -Wall 您可能希望将其与 -std=XX 其中xx是(c89 gnu89 c99 gnu99…)之一,和/或可能 -pedantic 哪一个更烦人的书呆子(或更多的是一个*保留取决于你的心情:)

    顺便说一句,您忘记包含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) 
    

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

    我想知道“缺少警告”消息是否是因为C类型的提升规则。(见K&R C编程语言,第2版,第2.7节- 类型转换 )只是思考的食物。

    我希望这有帮助。

    编辑以添加其他材料 (如下所示):

    另一种选择或方法是 splint (安全编程lint)或 Gimple Software 's pc lint/flexlint whuch是 lint 标记的C源代码的静态分析的实现 可疑和不可移植的结构。


    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's的flexlint中尝试这个例子。 Online Testing 比较干净,产量也不错。

        4
  •  0
  •   Bastien Léonard    16 年前

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