风险
问题描述:
我有主要有两种编译警告:风险
1的功能
隐含的声明中a.c
,它有char *foo(char *ptr1, char *ptr2)
,在b.c
,某些功能使用此功能foo
没有任何声明,我发现似乎编译器会将函数foo
的返回值视为整数,甚至我可以通过一些变量少于或超过foo
函数声明
2.枚举类型与其他类型的混合
我的目标芯片是ARM11,似乎连我自己都不解决这两种编译警告,我的程序可以在不遇到任何问题,但我相信它一定背后有一些风险。任何人都可以给我一些很好的例子,这两种编译警告可能会导致一些意想不到的问题?同时,如果这两个警告存在潜在风险,为什么c编译器允许这些类型的警告发生,但不会将它们直接设置为错误?任何背后的故事?
答
隐式声明。例如。你有功能:float foo(float a)
,当你调用它时没有声明。隐式规则将创建具有以下签名的自动声明:int foo(double)
(如果传递参数为float)。所以你通过的价值将转化为双倍,但foo
预计float
。与返回相同 - 调用代码期望int
,但返回float
。价值将是一个完整的混乱。
enum混合其他类型。枚举类型具有可能需要的值列表。如果您尝试为其分配数值,则有可能它不是列出的值之一;如果以后你的代码只能指定范围,并假设没有其他东西可以在那里 - 它可能会失败。
答
简单的例子:
文件:warn.c
#include <stdio.h>
double foo(double x)
{
return myid(x);
}
int
main (void)
{
double x = 1.0;
fprintf (stderr, "%lg == %lg\n", x, foo (x));
return 0;
}
文件:foo.c的
double
myid (double x)
{
return x;
}
编译并运行:
$ gcc warn.c foo.c -Wall
warn.c: In function ‘foo’:
warn.c:5: warning: implicit declaration of function ‘myfabs’
$ ./a.out
1 == 0
旧C标准( C90)有这个奇怪的“默认int”rul e和兼容性,即使在最新的编译器中也支持它。
不要将警告视为风险,而应视为*有用的帮助*。始终启用它们('gcc -Wall -Wextra'),并始终改进您的代码以避免它们。有时你会得到误报。其中大部分都不是错误,因为C99标准要求。当心[未定义的行为](http://en.wikipedia.org/wiki/Undefined_behavior) – 2014-10-29 08:12:40
现在可能不是问题,但将来会有问题。几周后,你想改变你的代码。如果你已经解决了所有警告,编译器可以告诉你,你的新修改可能会被破坏或错误。想象一下,你例如在新版本中将参数添加到foo函数中。使用头文件中声明的函数,编译器会告诉你,你必须在所有地方纠正它,但没有它,它会编译但不能正常工作。 – j123b567 2014-10-29 08:23:01