If I understand your question correctly, you've got something like this:
derpfoo.h:
#ifndef DERPFOO_H
#define DERPFOO_H
#include "derpbar.h"
typedef struct {
char *nothing;
} FOO;
BAR foo (BAR derp) {
return derp;
}
#endif
derpbar.h:
#ifndef DERPBAR_H
#define DERPBAR_H
#include "derpfoo.h"
typedef struct {
char *nothing;
} BAR;
FOO bar (FOO derp) {
return derp;
}
#endif
and then a simple derp.c:
#include "derpfoo.h"
#include "derpbar.h"
int main (void) {
return 0;
}
A friend of mine presented me with this problem in some SDL code a while ago, and it took me a while to understand both why he was doing what he was doing and how to fix it reasonably.
The intention of separating the code like this is that derpfoo and derpbar are logically separate, but they are also, sadly, mutually dependent. The simplest solution I've found to such a thing is to combine them and split them according to anatomy rather than logic like so:
derpstructs.h:
#ifndef DERPSTRUCTS_H
#define DERPSTRUCTS_H
typedef struct {
char *nothing;
} FOO;
typedef struct {
char *nothing;
} BAR;
#include "derpfunctions.h"
#endif
derpfunctions.h:
#ifndef DERPFUNCTIONS_H
#define DERPFUNCTIONS_H
#include "derpstructs.h"
BAR foo (BAR derp) {
return derp;
}
FOO bar (FOO derp) {
return derp;
}
#endif
and still a simple derp.c:
#include "derpstructs.h"
#include "derpfunctions.h"
int main (void) {
return 0;
}
Note that derpstructs.h includes derpfunctions.h at the end rather than at the beginning. This is not, strictly speaking, necessary, but if you do intend to have them include each other, you must include the function definitions after the struct definitions that they depend on, in all possible inclusion paths. Moving on...
This solution works, but it's not exactly sticking with the original philosophy that caused the problem to begin with -- that the two parts are logically separate, and should be kept so in the code.
The answer to both is to split everything up further, and tweak the inclusion paths even more.
derpfoostructs.h includes derpbarstructs.h first and then defines struct FOO and then at the end optionally includes derpfoofunctions.h and derpbarfunctions.h.
derpbarstructs.h includes derpfoostructs.h first and then defines struct BAR and then at the end optionally includes derpfoofunctions.h and derpbarfunctions.h.
derpfoofunctions.h includes derpfoostructs.h and derpbarstructs.h first, then includes derpbarfunctions.h, and then defines its functions.
derpbarfunctions.h includes derpfoostructs.h and derpbarstructs.h first, then includes derpfoofunctions.h, and then defines its functions.
derp.c includes derpfoostructs.h and derpbarstructs.h and then includes derpfoofunctions.h and derpbarfunctions.h, and then goes on to do whatever else it needs to do.
This satisfies both of the desired requirements. It eliminates circular dependencies, and still maintains logical separation of the two logically separate code units. You get two files to edit when you change from project to project instead of one, but it at least keeps the mutable code apart from the immutable. That, and it's the only solution I've found.
Hope this helped. Good luck on your projects.