OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libstdc++-v3/] [docs/] [html/] [17_intro/] [HEADER_POLICY] - Blame information for rev 20

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 20 jlechner
 
2
Header Policy
3
-------------
4
 
5
The C++ Standard specifies many mutual dependencies among the
6
headers it defines.  It offers no advice on how to arrange headers
7
to avoid problems.  The worst such problem is circular references.
8
Most simply this is "A includes B, B includes A":
9
 
10
  // file                      // file 
11
  #ifndef A                       #ifndef B
12
  #define A 1                     #define B 1
13
  #include                     #include 
14
  typedef int A_type;             typedef int B_type;
15
  extern B_type g(A_type);        extern A_type f(B_type);
16
  #endif /* A */                  #endif /* B */
17
 
18
  // file C.cc
19
  #include 
20
 
21
The typical effect of such an "include loop" may be seen by tracing
22
the preprocessor activity:
23
 
24
  C  // file C.cc
25
  C  #include 
26
  A    // file 
27
  A    #ifndef A
28
  A    #define A 1
29
  A    #include 
30
  B      // file 
31
  B      #ifndef B
32
  B      #define B 1
33
  B      #include 
34
  A        // file 
35
  A        #ifndef A           <-- oops, cpp symbol A defined already
36
  A        ...                 <-- skip  contents
37
  A        #endif
38
  B      typedef int B_type;
39
  B      extern A_type f(B_type);  <-- error, A_type not defined yet.
40
  B      #endif /* B */
41
  A    typedef int A_type;
42
  A    extern B_type g(A_type);
43
  A    #endif /* A */
44
 
45
The main symptom of #include loops is that definitions from file 
46
are not available after the #include  for certain include orders.
47
The number of standard headers makes testing all permutations of
48
include order impractical, so a policy is needed to prevent chaos.
49
In any case, for some standard headers (as for the above) no ordering
50
can eliminate the loop.
51
 
52
Other factors influence the policy.  Typical implementations of
53
Make (unfortunately including GNU make) have bugs relating to file
54
names with no suffix, that lead to such problems as failure to track
55
dependencies on such files and an inclination to _delete_ them.
56
Therefore, headers used in building the library are always of the
57
form  generally, or specifically  for
58
an equivalent to the standard header .
59
 
60
Standard headers  are all placed under directory std/, and
61
are ignored except during installation.  These headers simply
62
#include the corresponding header .
63
 
64
Standard substitute headers  that have any complexity
65
may sub-include other headers.  When they sub-include non-standard
66
headers, they first include all the headers required for that
67
non-standard header.
68
 
69
Mutual dependencies are handled by splitting up the declarations
70
intended for standard headers among two or more files, and then
71
interleaving them as needed.  For example, we replace  and 
72
above, as follows:
73
 
74
  // file 
75
  #ifndef _CPP_A
76
  #define _CPP_A
77
  # include 
78
  # include 
79
  # include 
80
  #endif
81
 
82
  // file 
83
  #ifndef _CPP_B
84
  #define _CPP_B
85
  # include 
86
  # include 
87
  # include 
88
  #endif
89
 
90
  // file 
91
  #ifndef _CPP_BITS_A_TYPES_H
92
  #define _CPP_BITS_A_TYPES_H
93
  typedef int A_type;
94
  #endif
95
 
96
  // file 
97
  #ifndef _CPP_BITS_B_TYPES_H
98
  #define _CPP_BITS_B_TYPES_H
99
  typedef int B_type;
100
  #endif
101
 
102
  // file 
103
  #ifndef _CPP_BITS_A_FUNS_H
104
  #define _CPP_BITS_A_FUNS_H
105
    extern B_type g(A_type);
106
  #endif
107
 
108
  // file 
109
  #ifndef _CPP_BITS_B_FUNS_H
110
  #define _CPP_BITS_B_FUNS_H
111
    extern A_type f(B_type);
112
  #endif
113
 
114
Of course we have the standard headers under their mandated names:
115
 
116
  // file 
117
  #ifndef _CPP_A
118
  #define _CPP_A
119
  # include 
120
  #endif
121
 
122
  // file 
123
  #ifndef _CPP_B
124
  #define _CPP_B
125
  # include 
126
  #endif
127
 
128
Notice that the include guards are named uniformly except that
129
the guard for standard header  is just _CPP_A,
130
identically as the header  in std/.
131
 
132
At installation the files std/* can be replaced by symbolic links,
133
or simply copied into place as is.  The result is:
134
 
135
  include/
136
  include/A -> bits/std_A.h
137
  include/B -> bits/std_A.h
138
  include/bits/
139
  include/bits/std_A.h
140
  include/bits/std_B.h
141
  include/bits/A_types.h
142
  include/bits/B_types.h
143
  include/bits/A_funs.h
144
  include/bits/B_funs.h
145
 
146
 
147
Of course splitting up standard headers this way creates
148
complexity, so it is not done routinely, but only in response
149
to discovered needs.
150
 
151
Another reason to split up headers is for support of separate
152
compilation of templates.  This interacts with the foregoing
153
because template definitions typically have many more dependencies
154
on other headers than do pure declarations.  Non-inline template
155
definitions are placed in a separate ".tcc" file that is included
156
by the standard header, and any other standard header that
157
requires definitions from it for its implementation.
158
 
159
The key to preventing chaos, given the above structure, is:
160
 
161
  Only standard headers  should sub-include
162
  other headers.
163
 
164
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.