Without inclusion guards, there would indeed be a problem. But with inclusion guards, it's not a problem, as long as you wrap the #include inside the guards.
Code:
/* one.h */
#ifndef ONE_H
#define ONE_H
#include "two.h"
/* ... code ... */
#endif
Code:
/* two.h */
#ifndef TWO_H
#define TWO_H
#include "one.h"
/* ... code ... */
#endif
That would compile just fine.
Are you familiar with inclusion guards? If not, I could explain them . . .
[edit] [This assumes familiarity with the preprocessor.]
When the compiler sees #include "two.h" inside one.h, it ends up with
Code:
/* one.h */
#ifndef ONE_H
#define ONE_H
/* two.h */
#ifndef TWO_H
#define TWO_H
#include "one.h"
/* ... code ... */
#endif
/* ... code ... */
#endif
Right, good so far. Now it sees that #include "one.h" and gets
Code:
/* one.h */
#ifndef ONE_H
#define ONE_H
/* two.h */
#ifndef TWO_H
#define TWO_H
/* one.h */
#ifndef ONE_H
#define ONE_H
#include "two.h"
/* ... code ... */
#endif
/* ... code ... */
#endif
/* ... code ... */
#endif
However, that red code is discarded. Why? Because the #ifndef ONE_H macro is false. So in the end, the code in one.h and the code in two.h is included once and once only.
The morale of the tale: Use inclusion guards, in case you perchance recursively include your header files. [/edit]