我最近对某些变量从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
真正的解决方案是升级我的编译器。由于复杂的原因(叹息),公司不愿意这样做。
答案 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)。