home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / lang / cplus / 16102 < prev    next >
Encoding:
Text File  |  1992-11-11  |  2.8 KB  |  94 lines

  1. Path: sparky!uunet!destroyer!sol.ctr.columbia.edu!usc!usc!not-for-mail
  2. From: coller@alnitak.usc.edu (Lee D. Coller)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Multiple Header Files Problem
  5. Date: 11 Nov 1992 10:35:40 -0800
  6. Organization: University of Southern California, Los Angeles, CA
  7. Lines: 82
  8. Message-ID: <1drjpsINN1jr@alnitak.usc.edu>
  9. References: <rmartin.721359424@thor> <1992Nov10.104447.12882@us-es.sel.de> <rmartin.721442494@thor>
  10. NNTP-Posting-Host: alnitak.usc.edu
  11.  
  12. In article <rmartin.721442494@thor> rmartin@thor.Rational.COM (Bob Martin) writes:
  13. >reindorf@us-es.sel.de (Charles Reindorf) writes:
  14. >
  15. >|In article <rmartin.721359424@thor>, rmartin@thor.Rational.COM (Bob Martin) writes:
  16. >||> A more interesting variation on this issue is the problem of "circular
  17. >||> 
  18. >||> [ etc.]
  19. >
  20. >|It is usual, in header files, to structure them so :
  21. >
  22. >
  23. >|| # ifndef <HeaderFileName>_h
  24. >|| # define <HeaderFileName>_h
  25. >|| 
  26. >|| 
  27. >|| ... body of include file ...
  28. >|| 
  29. >|| 
  30. >|| # endif
  31. >
  32. >|This prevents cyclic dependencies and has been in common practice for, well, ages.
  33. >
  34. >Of course!  And of course I use this technique myself, and instruct my
  35. >students to do the same. 
  36. >
  37. >What I had not realized, until you (and many others) pointed it out to
  38. >me, is that the #ifndef convention breaks inclusion cycles.  Of course
  39. >it does.
  40. >
  41.  
  42. Actually it doesn't entirely solve the circular dependency problem.
  43. Consider two files, file a.h containing:
  44.  
  45. #ifndef a_h
  46. #define a_h
  47.  
  48. #include "b.h"
  49.  
  50. class a {
  51. public:
  52.     b* _b;
  53.     void do_b_fnc() { _b->b_fnc(); }
  54.     void a_fnc();
  55. };
  56. #endif
  57.  
  58. File b.h contains:
  59.  
  60. #ifndef b_h
  61. #define b_h
  62.  
  63. #include "a.h"
  64.  
  65. class b {
  66. public:
  67.     a* _a;
  68.     void do_a_fnc() { _a->a_fnc(); }
  69.     void b_fnc();
  70. };
  71. #endif
  72.  
  73. Now if file a.c includes a.h, the compiler will generate an error at the
  74. "a* _a;" line because a is undefined.  But how can this be because b.h
  75. includes a.h which defines a?  The reason is by the time we get to b.h's
  76. inclusion of a.h, a_h is already defined, but the class definition of
  77. a has not been read.  When b.h includes a.h, the contents are skipped
  78. because of the a_h is already defined.  Note that doing a forward
  79. reference to "a" does not solve the problem because do_a_fnc() inline
  80. needs a's definition.
  81.  
  82. I think this was the reason Bob mentioned in an earlier posting to avoid
  83. inline definitions which require the inclusion of an additional header,
  84. as there is no clean fix to this problem.  In this simple example the
  85. problem is easy to track down, but I have seen examples in more complex
  86. programs where it has taken several hours to track down the location
  87. of the circularity.
  88.  
  89. -- 
  90. -----------------------------------------------------------------
  91. Lee D. Coller (coller@alnitak.usc.edu)        +1 (310) 379-0844
  92. USC Behavioral Technology Labs, 250 N. Harbor Dr. Ste 309
  93. Redondo Beach, California, 90277
  94.