我在项目中遇到了一些奇怪的gcc警告。让我们看看3个文件中的这个简单示例:
typedef struct {
int a;
long b;
char *c;
} myStruct;
#include <stdio.h>
#include <stdlib.h>
#include "struct.h"
myStruct* func() {
myStruct* new = (myStruct*) malloc(sizeof(myStruct));
new->a = 42;
new->b = 84;
new->c = "lol_ok\n";
return new;
}
void prn(myStruct* x) {
printf("%d\n", x->a);
}
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include "struct.h"
int main() {
myStruct* ms = func();
prn(ms);
return 0;
}
所以我收到以下警告:
main.c: In function ‘main’:
main.c:8:24: warning: initialization makes pointer from integer without a cast
myStruct* ms = func();
此外,当我使用-Wall -Wextra
构建它时,我得到更多:
main.c: In function ‘main’:
main.c:8:9: warning: implicit declaration of function ‘func’ [-Wimplicit-function-declaration]
myStruct* ms = func();
^
main.c:8:24: warning: initialization makes pointer from integer without a cast
myStruct* ms = func();
^
main.c:9:2: warning: implicit declaration of function ‘prn’ [-Wimplicit-function-declaration]
prn(ms);
这一切意味着什么?如果使用-fsanitize=undefined -fsanitize=address
构建并且很奇怪,它也会崩溃。为什么呢?
答案 0 :(得分:4)
缺乏原型。
在func()
中包含struct.h
的原型。
myStruct* func(void);
当func()
没有可见的原型时,编译器假定(在C99之前)它返回int
。但func()
实际上会返回myStruct*
。
请注意,此隐式int规则已从C99 删除。从技术上讲,你的代码在C99和C11中是不正确的。
提高警告级别会有所帮助。 gcc提供an option来抓住这个:
-Wimplicit-function-declaration
答案 1 :(得分:4)
main.c:8:9: warning: implicit declaration of function ‘func’ [-Wimplicit-function-declaration]
这意味着main.c不知道函数func
是什么样的。那是因为它是在func.c中定义的,但是main.c看不到func.c中的内容。
您需要做的是在struct.h中放置func()
的声明,如下所示:
myStruct* func( void );
一旦你有了,那么main.c知道函数func
是什么。
...
此外,你得到“初始化使得指针来自没有强制转换的整数”的原因是因为没有看到函数的声明,编译器假定它返回int
。