Take the 2-minute tour ×

The question seems to be a classic one, but I didn't find an answer:

I have two struct type written in C ------ struct type A and struct type B, and B use A while A use B at the same time.

In a.h:

#include "b.h"
struct B;
typedef struct A {
    void (*func)(struct B* b);

In b.h:

#include "a.h"
typedef struct B {
    A a;

though this will work, it has a consequence --- when using the function fun "func", if I pass a variable declared in the form:

B* someb;


struct B* someb;

there will be a warning when compiling, saying incompatible pointer type. Is this normal? could I avoid this warning?

share|improve this question
stackoverflow.com/questions/252780/… –  Mat Feb 25 '12 at 9:45
What did you try? –  Alexey Frunze Feb 25 '12 at 9:47
Sorry, but what I want to do i to avoid the warning, as I want to use "B someb;" to define variables rather than "struct B someb;" through all cases. Is that possible? –  realjin Feb 25 '12 at 9:55
@user816109 : sure - see the answer below ;) –  Sander De Dycker Feb 25 '12 at 10:11

4 Answers 4

up vote 2 down vote accepted

From your a.h header file, simply remove the line #include "b.h". The forward declaration struct B; is all you need.

That change will fix the circular include dependency, and will make any code using these headers more sane.

Then, wherever you want to make use of the B struct, simply include b.h, and use it with or without the struct keyword.

Some code to illustrate : the a.h header file :

/* a.h */
struct B;

typedef struct A {
    void (*func)(struct B* b);
} A;

The b.h header file :

/* b.h */
#include "a.h"

typedef struct B {
    A a;
} B;

A file that uses these header files :

/* some_file.c */
#include "b.h"

void fun() {
    B someb;

void fun2() {
    struct B someb;

Both fun and fun2 are just fine (from the compiler point of view - func hasn't been initialized, so calling it will cause an issue at run time).

share|improve this answer
yeah, you are right! I miss the forward declaration. BTW, could you tell me how could I be clear of compiler's view of struct like you(i.e. these trival things about struct declaration)? what kind of material can I read? –  realjin Feb 25 '12 at 11:07
@realjin : the compiler is happy when your code is syntactically correct. So, knowing the C syntax in detail helps a lot. While the C standard is the definitive resource, it's a bit difficult to read. But any good resource on C will teach you much already. –  Sander De Dycker Feb 25 '12 at 16:46
ok, I see, thanks! –  realjin Mar 4 '12 at 4:57

Cyclic include dependencies are never a good idea.

The simplest way is to have forward declarations for the struct tag and the typedef in "a.h"

typedef struct A A;
typedef struct B B;
share|improve this answer
thanks, you pointed the key thing --- I missed the forward declarations. –  realjin Feb 25 '12 at 13:41

The struct whatever { /* ... */ }; defines a new type.
That new type name is struct whatever.

You can define another name for the type with typedef either in the same statement that defines the type

typedef struct whatever { /* ... */ } newtypename;

or in a different statement

struct whatever { /* ... */ };
typedef struct whatever newtypename;

You can even define a struct type with no name and get a new name for it

typedef struct { /* ... */ } newtypenameforstructwithnotag;
share|improve this answer

Function func as you declared it gets as input a pointer to a struct B object, so when calling the function you should do like this:

B* somePointer; //because of your typedef you can omit struct 

I omitted the part of allocation of memory you should also manage...

As SO question Compiler Warning: Initialization incompatible pointer type shows, you should pass a pointer to the function in order to make changes visible in the object, otherwise you are just passing a copy of struct B and every change you make will only last in the functions scope.

I believe that's the reason of the warning.

share|improve this answer
Just as I mentioned in the comments below the question, my program runs well, what I want to do is to avoid the warning. –  realjin Feb 25 '12 at 9:57
@user816109 incompatible pointer type is a typical warning when you're messing up with pointers arguments that don't match with the predefined standard. My guess is that the reason of this warning is because of what I pointed out, you are free to accept this suggestion or not. –  Matteo Feb 25 '12 at 10:03
sorry I made a typo --- that should be "B* someb;" and "struct B* someb;". I've corrected it just now. –  realjin Feb 25 '12 at 11:09
@user816109 no problem!glad you found your answer –  Matteo Feb 25 '12 at 11:30

Your Answer


