奇怪的gcc警告和消毒剂崩溃

时间:2015-12-08 20:30:47

标签: c gcc compiler-warnings

我在项目中遇到了一些奇怪的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构建并且很奇怪,它也会崩溃。为什么呢?

2 个答案:

答案 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