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