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

  1. Path: sparky!uunet!mcsun!sunic!hagbard!loglule!jbn
  2. From: jbn@lulea.trab.se (Johan Bengtsson)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Multiple Header Files Problem
  5. Message-ID: <5189@holden.lulea.trab.se>
  6. Date: 11 Nov 92 12:59:26 GMT
  7. References: <1992Nov10.164547.19059@mprgate.mpr.ca>
  8. Organization: Telia Research AB, Aurorum 6, 951 75 Lulea, Sweden
  9. Lines: 82
  10. X-Newsreader: Tin 1.1 PL4
  11.  
  12. walduck@mpr.ca (Andrew Walduck) writes:
  13. : In article <rmartin.721359424@thor> rmartin@thor.Rational.COM (Bob Martin) writes:
  14. : >A more interesting variation on this issue is the problem of "circular
  15. : >inclusion".  Consider a source file: "a.h" which includes "b.h".
  16. : >However, "b.h" includes "a.h".  This trivial example will fail to
  17. : >compile.  Unless the compiler is very clever (I haven't seen one yet),
  18. : >it will sit and spin until it exhauses some resouce (usually memory),
  19. : >and then it will die a horrible death.  If it prints an error at all,
  20. : >the error is nearly certain to have nothing to do with the circular
  21. : >containment.
  22. : Why not just wrap your headers in:
  23. : #ifndef someUniqueIdentiferPerFile_inc
  24. : #define someUniqueIdentiferPerFile_inc
  25. : #include <someotherfile.h>
  26. : // grotty code goes here...
  27. : #endif
  28.  
  29. (I'm sure Bob is aware of this idiom)
  30.  
  31. You still get problems with circularities, although you do not
  32. cause the compiler to loop forever:
  33.  
  34. // a.hh
  35. #ifndef A_HH
  36. #define A_HH
  37. #include "b.hh"
  38. // code for "a", needs stuff in "b.hh"
  39. #endif
  40.  
  41. // b.hh
  42. #ifndef B_HH
  43. #define B_HH
  44. #include "a.hh"
  45. // code for "b", needs stuff in "a.hh"
  46. #endif
  47.  
  48. // main.cc
  49. #include "a.hh"
  50.  
  51. Problem is that a.hh gets #included, #includes b.hh, which tries to
  52. #include a.hh.  This will fail, since b.hh will not see all declarations
  53. in a.hh (A_HH is already defined).
  54.  
  55. In general, circular #includes is a clear indication that you should
  56. revise your source file structure.  Sometimes it is possible to factor out
  57. a common header file, which both a.hh and b.hh #includes.  If a.hh and b.hh
  58. represent collaborating classes, then it is sometimes useful to create a
  59. new "broker" class that forwards request between the classes.  As Bob said,
  60. using forward declarations instead of $includes helps too.
  61.  
  62. B.T.W., you should regularly analyze your #include dependencies not only
  63. to find circularities, but also for the sake of cleaning up unnecessary
  64. #includes.  If you define the #include patterns during design, you can
  65. also compare that with what is actually there in the source code.
  66. The following trivial AWK script is a start:
  67.  
  68. #!/bin/awk -f
  69. #
  70. # includes - AWK script that analyses C/C++ source files
  71. #            Generates output of the form
  72. #
  73. #            prog.c Includes "interface.h"
  74. #            prog.c Includes <stdio.h>
  75. #            interface.h Includes <string.h>
  76. #
  77. /^[     ]*#include/ {
  78.                 print FILENAME, "Includes", substr( $2, 2, length($2)-2 )
  79.    ^^^^^
  80.    this is a space and a TAB
  81.  
  82. Feed it to your favorite graphical layout tool (:-), or use a nice
  83. environment that provides #include graphs.
  84.  
  85. -- 
  86. --------------------------------------------------------------------------
  87. | Johan Bengtsson, Telia Research AB, Aurorum 6, S-951 75 Lulea, Sweden  |
  88. | Johan.Bengtsson@lulea.trab.se; Voice:(+46)92075471; Fax:(+46)92075490  |
  89. --------------------------------------------------------------------------
  90.