I have this code:
main.h
#ifndef MAINH
#define MAINH
...
#include "my_struct.h"
void some_func(my_structure *x);
...
#endif
and
my_struct.h
#ifndef UTILSH
#define UTILSH
...
#include "main.h"
...
typedef struct abcd {
int a;
} my_structure;
...
#endif
but I'm getting this when I try to compile: error: unknown type name ‘my_structure’
Any idea why?
Because of how you've ordered your includes, the compiler sees void some_func(my_structure *x);
before it sees typedef struct abcd { int a; } my_structure;
.
I think.
Let's walk this through.
Assuming my_struct.h
is processed first, we get the following sequence of events:
UTILSH
is defined
MAINH
is defined
- Because
UTILSH
is already defined, we don't process my_struct.h
again, so the typedef isn't processed
void some_func(my_structure *x);
is processed.
- Now the typedef is processed.
So after preprocessing, your compiler sees the following sequence of declarations:
...
void some_func(my_structure *x);
...
typedef struct abcd {...} my_structure;
Bad juju. You either need a forward declaration of my_structure
in main.h
, or you need to break that circular dependency (which is the much preferred option). Is there anything in main.h
that my_structure.h
actually uses? If so, you will want to factor it out into a separate file that both main.h
and my_structure.h
include.
You created a circular header inclusion. Circular inclusion never achieves anything. It is infinite. The #ifndef
include guard will break the infinite inclusion circle at some unpredictable point (depending on which header is included into .c
file first). This is what happened in your case. Basically, your circular inclusion got "resolved" into including main.h
first and my_struct.h
second. This is why main.h
knows nothing about my_struct
type.
Again, circular inclusion never achieves anything. Get rid of circular inclusion. Design your header structure hierarchically: lower-level headers included into higher-level headers, but never the other way around. In your case my_struct.h
is probably a lower-level header, which means that you have to stop including main.h
into my_struct.h
. Redesign your headers so that my_struct.h
no longer needs main.h
.
The error message is coming from main.h
while it's included in my_struct.h
, before my_structure
is defined. You should rethink your include paths since main.h
and my_struct.h
include each other.
You probably want your main.h
file to just include my_struct.h
, and not have my_struct.h
to include anything. You're essentially instructing your C compiler to have an infinite co-include loop.