风险

问题描述:

我有主要有两种编译警告:风险

1的功能

隐含的声明中a.c,它有char *foo(char *ptr1, char *ptr2),在b.c,某些功能使用此功能foo没有任何声明,我发现似乎编译器会将函数foo的返回值视为整数,甚至我可以通过一些变量少于或超过foo函数声明

2.枚举类型与其他类型的混合

我的目标芯片是ARM11,似乎连我自己都不解决这两种编译警告,我的程序可以在不遇到任何问题,但我相信它一定背后有一些风险。任何人都可以给我一些很好的例子,这两种编译警告可能会导致一些意想不到的问题?同时,如果这两个警告存在潜在风险,为什么c编译器允许这些类型的警告发生,但不会将它们直接设置为错误?任何背后的故事?

+0

不要将警告视为风险,而应视为*有用的帮助*。始终启用它们('gcc -Wall -Wextra'),并始终改进您的代码以避免它们。有时你会得到误报。其中大部分都不是错误,因为C99标准要求。当心[未定义的行为](http://en.wikipedia.org/wiki/Undefined_behavior) – 2014-10-29 08:12:40

+1

现在可能不是问题,但将来会有问题。几周后,你想改变你的代码。如果你已经解决了所有警告,编译器可以告诉你,你的新修改可能会被破坏或错误。想象一下,你例如在新版本中将参数添加到foo函数中。使用头文件中声明的函数,编译器会告诉你,你必须在所有地方纠正它,但没有它,它会编译但不能正常工作。 – j123b567 2014-10-29 08:23:01

隐式声明。例如。你有功能:float foo(float a),当你调用它时没有声明。隐式规则将创建具有以下签名的自动声明:int foo(double)(如果传递参数为float)。所以你通过的价值将转化为双倍,但foo预计float。与返回相同 - 调用代码期望int,但返回float。价值将是一个完整的混乱。

enum混合其他类型。枚举类型具有可能需要的值列表。如果您尝试为其分配数值,则有可能它不是列出的值之一;如果以后你的代码只能指定范围,并假设没有其他东西可以在那里 - 它可能会失败。

+0

好吧,我可以知道为什么c编译器默认允许“隐式声明”吗?这背后的故事? – 2014-10-29 08:02:02

+1

由于历史原因。有一个答案http://stackoverflow.com/questions/11835001/why-does-did-c-allow-implicit-function-and-typeless-variable-declarations – j123b567 2014-10-29 08:06:49

+0

历史原因。 C99 +禁止隐式声明。 C++也是如此。 – keltar 2014-10-29 09:03:36

简单的例子:

文件: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和兼容性,即使在最新的编译器中也支持它。