miloserdow
miloserdow

Reputation: 1087

Weird gcc warning and sanitizer crash

I've encountered some weird gcc warning in my project. Let's look at this simple example in 3 files:

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;
}

So I get the following warning:

main.c: In function ‘main’:
main.c:8:24: warning: initialization makes pointer from integer without a cast
         myStruct* ms = func();

Moreover when I build it with -Wall -Wextra I get more:

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);

What does it all mean? It also crashes if built with -fsanitize=undefined -fsanitize=address and that's weird. Why?

Upvotes: 4

Views: 122

Answers (2)

P.P
P.P

Reputation: 121397

Lack of prototype.

Include the prototype for func() in struct.h.

myStruct* func(void);

When there's no prototype visible for func(), compiler assumes (pre-C99) that it returns an int. But func() actually returns an myStruct*.

Note that this implicit int rule has been removed from C99. So technically, your code is ill-formed in C99 and C11.

Increasing your warning level would help. gcc provides an option to catch this:

-Wimplicit-function-declaration

Upvotes: 5

Andy Lester
Andy Lester

Reputation: 93676

main.c:8:9: warning: implicit declaration of function ‘func’ [-Wimplicit-function-declaration]

That means that main.c doesn't know what the function func looks like. That's because it's defined in func.c, but main.c can't see what's in func.c.

What you need to do is put a declaration for func() in struct.h, like so:

myStruct* func( void ); 

Once you have that there, then main.c knows what the function func is.

....

Also, the reason you get "initialization makes pointer from integer without a cast" is because without seeing a declaration of the function, the compiler assumes it returns int.

Upvotes: 4

Related Questions