Reputation: 1087
I've encountered some weird gcc warning in my project. Let's look at this simple example in 3 files:
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;
}
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
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
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