home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!destroyer!sol.ctr.columbia.edu!usc!usc!not-for-mail
- From: coller@alnitak.usc.edu (Lee D. Coller)
- Newsgroups: comp.lang.c++
- Subject: Re: Multiple Header Files Problem
- Date: 11 Nov 1992 10:35:40 -0800
- Organization: University of Southern California, Los Angeles, CA
- Lines: 82
- Message-ID: <1drjpsINN1jr@alnitak.usc.edu>
- References: <rmartin.721359424@thor> <1992Nov10.104447.12882@us-es.sel.de> <rmartin.721442494@thor>
- NNTP-Posting-Host: alnitak.usc.edu
-
- In article <rmartin.721442494@thor> rmartin@thor.Rational.COM (Bob Martin) writes:
- >reindorf@us-es.sel.de (Charles Reindorf) writes:
- >
- >|In article <rmartin.721359424@thor>, rmartin@thor.Rational.COM (Bob Martin) writes:
- >||> A more interesting variation on this issue is the problem of "circular
- >||>
- >||> [ etc.]
- >
- >|It is usual, in header files, to structure them so :
- >
- >
- >|| # ifndef <HeaderFileName>_h
- >|| # define <HeaderFileName>_h
- >||
- >||
- >|| ... body of include file ...
- >||
- >||
- >|| # endif
- >
- >|This prevents cyclic dependencies and has been in common practice for, well, ages.
- >
- >Of course! And of course I use this technique myself, and instruct my
- >students to do the same.
- >
- >What I had not realized, until you (and many others) pointed it out to
- >me, is that the #ifndef convention breaks inclusion cycles. Of course
- >it does.
- >
-
- Actually it doesn't entirely solve the circular dependency problem.
- Consider two files, file a.h containing:
-
- #ifndef a_h
- #define a_h
-
- #include "b.h"
-
- class a {
- public:
- b* _b;
- void do_b_fnc() { _b->b_fnc(); }
- void a_fnc();
- };
- #endif
-
- File b.h contains:
-
- #ifndef b_h
- #define b_h
-
- #include "a.h"
-
- class b {
- public:
- a* _a;
- void do_a_fnc() { _a->a_fnc(); }
- void b_fnc();
- };
- #endif
-
- Now if file a.c includes a.h, the compiler will generate an error at the
- "a* _a;" line because a is undefined. But how can this be because b.h
- includes a.h which defines a? The reason is by the time we get to b.h's
- inclusion of a.h, a_h is already defined, but the class definition of
- a has not been read. When b.h includes a.h, the contents are skipped
- because of the a_h is already defined. Note that doing a forward
- reference to "a" does not solve the problem because do_a_fnc() inline
- needs a's definition.
-
- I think this was the reason Bob mentioned in an earlier posting to avoid
- inline definitions which require the inclusion of an additional header,
- as there is no clean fix to this problem. In this simple example the
- problem is easy to track down, but I have seen examples in more complex
- programs where it has taken several hours to track down the location
- of the circularity.
-
- --
- -----------------------------------------------------------------
- Lee D. Coller (coller@alnitak.usc.edu) +1 (310) 379-0844
- USC Behavioral Technology Labs, 250 N. Harbor Dr. Ste 309
- Redondo Beach, California, 90277
-