Q? Warning: Implicit declaration of function xxx is invalid in C99???
A:问题经常出现在C中,字面意思就是隐式声明的函数在C99中无效!!
概念:
隐式声明:指如果没有关于被调函数的特定信息,编译器便假定在这个函数的调用时传递的参数类型和个数都是正确的,同时会假定函数返回一个整数类型的值。
【隐式声明的规则为:隐式声明的函数返回值都为int,参数类型则会根据你的入参来决定】
简单来说,在C语言中,函数在调用前不一定非要声明。如果没有声明,那么编译器会自己主动依照一种隐式声明的规则(规则就按照上述所述),为调用函数的C代码产生汇编代码。
例子:
int main(int argc, char** argv)
{
double x = function(5.5,8);
return 0;
}
单纯的编译上述源代码。并没有什么报错,仅仅是显示警告,隐式声明function函数。如前所述,之所以编译不会报错,是由于C语言规定,对于没有声明的函数,自己主动使用隐式声明。
但是,按照上述规则,相当于变成了以下代码:
int function(double x, int y)
int main(int argc, char** argv)
{
double x = function(5.5,8);
return 0;
}
可能带来的问题:
- 隐式声明函数名称恰好在链接库中存在,但返回非int类型
double function(double x, double y)
{
return x+y;
}
实际函数的定义和声明返回值类型和入参类型都不一致,风险很大。
2. 隐式声明函数名称恰好在链接库中存在。且返回int类型
此时,由于隐式声明的函数原型与gcc的内建函数原型全然同样。所以gcc不会给出不论什么警告,结果也是正确的。
上面是一个由于函数声明的入参类型不匹配和返回值类型不匹配导致的一个bug。在一个大工程里面这些BUG发生后会使DEBUG人员感到十分困惑,不容易调查。
如何避免:
四个字:编程规范,任何时候,都要声明函数。
解决方案:
- 在头文件中声明函数,即将要被使用的函数声明到.h文件中,
#include "xxxx.h" in the C code.
- 移动函数到第一次调用的前面。
- 显式声明在第一次调用前,实际是前2种组合,添加函数声明到.h文件中。
另请注意:如果函数只需要在实现它的文件中使用,则应将其声明为**静态(static)**的,以便仅在该单元中可见。