I have a couple of header files, which boil down to:
tree.h:
#include "element.h"
typedef struct tree_
{
struct *tree_ first_child;
struct *tree_ next_sibling;
int tag;
element *obj;
....
} tree;
and element.h:
#include "tree.h"
typedef struct element_
{
tree *tree_parent;
char *name;
...
} element;
The problem is that they both reference each other, so tree needs element to be included, and element needs tree to be included.
This doesn't work because to define the 'tree' structure, the element structure must be already known, but to define the element structure, the tree structure must be known.
How to resolve these types of loops (I think this may have something to do with 'forward declaration'?)?
These are known as "once-only headers." See http://developer.apple.com/DOCUMENTATION/DeveloperTools/gcc-4.0.1/cpp/Once_002dOnly-Headers.html#Once_002dOnly-Headers
IMHO the best way is to avoid such loops because they are a sign of physical couping that should be avoided.
For example (as far as I remember) "Object-Oriented Design Heuristics" purpose to avoid Include Guards because they only mask the cyclic (physical) dependency.
An other approach is to predeclare the structs like this:
tree.h: struct element_; struct tree_ { struct tree_* first_child; struct tree_* next_sibling; int tag; struct element_ *obj; };
The correct answer is to use include guards, and to use forward declarations.
Include Guards
Visual C++ also supports #pragma once. It is a non standard preprocessor directive. In exchange for compiler portability, you reduce the possibility of preprocessor name collisions and increase readability.
Forward Declarations
Forward declare your structs. If the members of a struct or class are not explicitly needed, you can declare their existence at the beginning of a header file.
I don't like forward declarations cause they are redundant and buggy. If you want all your declarations in the same place then you should use includes and header files with include guards.
You should think about includes as a copy-paste, when the c preprocesor finds an #include line just places the entire content of myheader.h in the same location where #include line was found.
Well, if you write include guards the myheader.h's code will be pasted only one time where the first #include was found.
If your program compiles with several object files and problem persists then you should use forward declarations between object files (it's like using extern) in order to keep only a type declaration to all object files (compiler mixes all declarations in the same table and identifiers must be unique).