关于Linux下特有的warning: implicit declaration of function "函数名" 错误

缘起

今天偶发现一个Linux下的警告,想了将近一天,通过搜索资料后得出的结果,分享给大家

首先上代码:

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static char * user;
int main(void)
{
user=rt_elem("sssss" , "ssss");
return 0;
}

//test.c

1
2
3
4
5
6
7
8
9
#include <string.h>
#include <stdlib.h>
char* rt_elem(char *id, char *passwd)
{
char *e = (char *)calloc(1, sizeof(char));
e = "Hello , World";
return e;
}

使用GCC编译后得出的结果:

1
2
3
4
C:\Users\Administrator\Desktop\main.c||In function 'main':|
C:\Users\Administrator\Desktop\main.c|12|warning: implicit declaration of function 'rt_elem'|
C:\Users\Administrator\Desktop\main.c|12|warning: assignment makes pointer from integer without a cast|
||=== Build finished: 0 errors, 2 warnings ===|

这个警告很诡异,虽然对整个结果没什么太大的影响,但是还是有必要了解下为什么以及怎么解决:

第一种解决方法

首先我得到的第一种解决方式是:

  1. 没有把函数所在的c文件生成.o目标文件。
  2. 在函数所在的c文件中定义了,但是没有在与之相关的.h文件中声明

这个只要编程的时候规范点,把头文件什么的都弄好就没事了

以下是第 2)中解决方法:

//test.h

1
char *rt_elem(char *id , char *passwd);

然后在main.c中添加头文件 #include "test.h"即可

第二种解决方法

第二种解决方式:
有人会问,那要我不是每个实现文件都要写一个声明文件呢?

我想到的方法:
在你写的每个函数的前面加上extern
像这样:

test.c

1
2
3
4
5
6
7
extern char* rt_elem(char *id, char *passwd)
{
char *e = (char *)calloc(1, sizeof(char));
e = "Hello , World";
return e;
}

这样,编译器就不会报错了,以下是再次编译信息

1
2
3
4
5
Compiling: C:\Users\Administrator\Desktop\test.c
Linking console executable: bin\Debug\Linux_test.exe
Output size is 26.26 KB
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 0 warnings

第三种解决方法

当然还有第三种解决方法,就是加上强制转换类型

比如在main.c中:

1
user = (char *)rt_elem(id , passwd);

不过这种方法治标不治本,最好不要用

OK ,那为什么会报这种错误呢?。以下是来自别人家的博客的一段话:

因为在头文件中定义的数据只能被其他文件包含一次,但是函数可以被其他函数重复包含多次;因此,一般情况下把数据和函数分别定义在不同的头文件中;如果定义在同一个头文件中,那么在重复包含函数的文件中使用extern function来包含相关函数。

热评文章