【问题标题】:How do I turn off erroneous float/long error messages from gcc如何关闭来自 gcc 的错误浮点/长错误消息
【发布时间】:2010-10-19 11:07:45
【问题描述】:

我最近将我们的代码库从浮点数更改为长整数,发现编译器在我知道仍然错误的区域没有生成错误消息。这导致我将 -Wconversion 添加到编译器标志中。但是,哎呀,这会导致一些虚假的错误消息。在下面的 sn-p 中,我得到了如上所述的错误。我能做些什么来根据具体情况抑制此消息,或者诱使 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。该死。阅读 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

真正的解决方案是升级我的编译器。公司出于复杂的原因不愿意做的事情(叹气)。

【问题讨论】:

    标签: c gcc gcc-warning


    【解决方案1】:

    只是从信息页面猜测,您尝试过-Wno-traditional-conversion吗?

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

    【讨论】:

    • 我刚才试了一下。没有帮助。感谢您的建议。
    • 我现在要做的就是说服公司不同分支机构的 3 层管理层升级我们的编译器。 :-(。感谢您的帮助。
    • 难道不能为了过渡而直接使用 gcc 4.3 编译代码,然后继续使用旧的编译器进行生产吗?
    • +1 有关 gcc 4.3 中-Wconversion 含义变化的评论,请参阅gcc.gnu.org/wiki/NewWconversion。
    【解决方案2】:

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

    -Wconversion

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

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


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

    【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      我相信您最有可能寻找的标志是 -Wall,您可能希望将其与 -std=XX 结合,其中 XX 是 (c89|gnu89) 之一|c99|gnu99|...), 和/或可能是 -pedantic 更令人讨厌的迂腐(或者更*lly保持记忆取决于你的心情:)

      顺便说一句,您忘记包含 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&R The C Programming Language,第 2 版,第 2.7 节 - 类型转换)。只是思考的食物。

      我希望这会有所帮助。

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

      另一个选项或方法是 splint(安全编程 Lint)或 Gimple Software 的 PC-lint / FlexLint,它们是 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 的 Online Testing 尝试使用 FlexLint 中的示例,该示例更简洁漂亮。

      【讨论】:

      • 我也喜欢添加 -Wextra 。
      猜你喜欢
      • 2010-10-29
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 2014-03-02
      • 2018-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多