奇怪的 gcc 警告和消毒剂崩溃
Weird gcc warning and sanitizer crash
我在我的项目中遇到了一些奇怪的 gcc 警告。让我们在 3 个文件中查看这个简单示例:
struct.h
typedef struct {
int a;
long b;
char *c;
} myStruct;
func.c
#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);
}
main.c
#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
构建,它也会崩溃,这很奇怪。为什么?
缺乏原型。
在 struct.h
中包含 func()
的原型。
myStruct* func(void);
当 func()
的原型不可见时,编译器假定(C99 之前)它 returns 是 int
。但是 func()
实际上 returns 一个 myStruct*
。
请注意,此隐式 int 规则已从 C99 删除。所以从技术上讲,您的代码在 C99 和 C11 中的格式不正确。
提高警告级别会有所帮助。 gcc 提供 an option 来捕捉这个:
-Wimplicit-function-declaration
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
是什么了。
.....
另外,你得到 "initialization makes pointer from integer without a cast" 的原因是因为没有看到函数的声明,编译器假定它 returns int
.
我在我的项目中遇到了一些奇怪的 gcc 警告。让我们在 3 个文件中查看这个简单示例:
struct.h
typedef struct {
int a;
long b;
char *c;
} myStruct;
func.c
#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);
}
main.c
#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
构建,它也会崩溃,这很奇怪。为什么?
缺乏原型。
在 struct.h
中包含 func()
的原型。
myStruct* func(void);
当 func()
的原型不可见时,编译器假定(C99 之前)它 returns 是 int
。但是 func()
实际上 returns 一个 myStruct*
。
请注意,此隐式 int 规则已从 C99 删除。所以从技术上讲,您的代码在 C99 和 C11 中的格式不正确。
提高警告级别会有所帮助。 gcc 提供 an option 来捕捉这个:
-Wimplicit-function-declaration
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
是什么了。
.....
另外,你得到 "initialization makes pointer from integer without a cast" 的原因是因为没有看到函数的声明,编译器假定它 returns int
.