2

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

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

4

4 回答 4

3

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

-W转换

如果原型导致的类型转换与没有原型时相同参数发生的类型转换不同,则发出警告。这包括定点到浮点的转换,反之亦然,以及改变定点参数的宽度或符号的转换,除非与默认提升相同。

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


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

于 2009-04-14T21:44:17.950 回答
2

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

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

于 2009-04-14T21:38:33.067 回答
2

我相信您最有可能寻找的标志是-Wall您可能希望与-std=XXXX 是 (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 节 -类型转换)。只是思考的食物。

我希望这有帮助。

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

另一种选择或方法是夹板 (安全编程 Lint)或Gimple Software的 PC-lint / FlexLint,它们是标记可疑和不可移植结构的 C 源代码的静态分析的lint实现。


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 的在线测试中尝试使用 FlexLint 中的示例,该示例更清晰、更漂亮。

于 2009-04-14T23:15:21.977 回答
0

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

于 2009-04-14T21:54:48.847 回答