Let's simplify the program by omitting the declaration and the useless main:
void foo(struct bar* p){}
The compiler sees struct bar, which has not been defined. The error message from GCC 4.8.2 explains what it does next:
a.c:1:17: warning: ‘struct bar’ declared inside parameter list [enabled by default] void foo(struct bar* p){} ^ a.c:1:17: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
So now it assumes that struct bar is something that only exists within the definition of foo. The code compiles perfectly, though.
When you add the function prototype:
void foo(struct bar* p); void foo(struct bar* p){}
the warning becomes:
a.c:1:17: warning: ‘struct bar’ declared inside parameter list [enabled by default] void foo(struct bar* p); ^ a.c:1:17: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default] a.c:3:17: warning: ‘struct bar’ declared inside parameter list [enabled by default] void foo(struct bar* p){} ^ a.c:3:6: error: conflicting types for ‘foo’ void foo(struct bar* p){} ^ a.c:1:6: note: previous declaration of ‘foo’ was here void foo(struct bar* p); ^
So like before, the compiler makes up a new, undefined type struct bar for the prototype, and another one for the function definition. So the prototype for foo and its definition refer to different types, both named struct bar. They don't match, hence the error.
The solution is to first forward-declare the struct:
struct bar; void foo(struct bar* p); void foo(struct bar* p){}
This compiles without warnings.
struct bardefined above, in between, or below these lines (or possibly not at all)?struct barmakes this error go away. Is your question "why is a not-defined type not equal to the same not-defined type"?