c-奇怪的gcc警告和消毒液崩溃



我在项目中遇到了一些奇怪的gcc警告。让我们在3个文件中看看这个简单的例子:

struct.h

typedef struct {
    int a;
    long b;
    char *c;
} myStruct;

函数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_okn";
    return new;
}
void prn(myStruct* x) {
    printf("%dn", 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之前)它返回一个int。但是func()实际上返回一个myStruct*

请注意,此隐式int规则已被从C99中删除。因此,从技术上讲,C99和C11中的代码格式不正确。

提高警告级别会有所帮助。gcc提供了一个捕捉这个的选项:

-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.中有什么。

您需要做的是将func()的声明放在struct.h中,如下所示:

myStruct* func( void ); 

一旦你有了它,那么main.c就知道函数func是什么了

此外,之所以得到"initialization make pointer from integer without a cast",是因为在没有看到函数声明的情况下,编译器假设它返回int

最新更新