Guard-Macros.html 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <!-- Created by GNU Texinfo 5.2, http://www.gnu.org/software/texinfo/ -->
  4. <head>
  5. <title>The GNU C Preprocessor Internals: Guard Macros</title>
  6. <meta name="description" content="The GNU C Preprocessor Internals: Guard Macros">
  7. <meta name="keywords" content="The GNU C Preprocessor Internals: Guard Macros">
  8. <meta name="resource-type" content="document">
  9. <meta name="distribution" content="global">
  10. <meta name="Generator" content="makeinfo">
  11. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  12. <link href="index.html#Top" rel="start" title="Top">
  13. <link href="Concept-Index.html#Concept-Index" rel="index" title="Concept Index">
  14. <link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
  15. <link href="index.html#Top" rel="up" title="Top">
  16. <link href="Files.html#Files" rel="next" title="Files">
  17. <link href="Line-Numbering.html#Line-Numbering" rel="prev" title="Line Numbering">
  18. <style type="text/css">
  19. <!--
  20. a.summary-letter {text-decoration: none}
  21. blockquote.smallquotation {font-size: smaller}
  22. div.display {margin-left: 3.2em}
  23. div.example {margin-left: 3.2em}
  24. div.indentedblock {margin-left: 3.2em}
  25. div.lisp {margin-left: 3.2em}
  26. div.smalldisplay {margin-left: 3.2em}
  27. div.smallexample {margin-left: 3.2em}
  28. div.smallindentedblock {margin-left: 3.2em; font-size: smaller}
  29. div.smalllisp {margin-left: 3.2em}
  30. kbd {font-style:oblique}
  31. pre.display {font-family: inherit}
  32. pre.format {font-family: inherit}
  33. pre.menu-comment {font-family: serif}
  34. pre.menu-preformatted {font-family: serif}
  35. pre.smalldisplay {font-family: inherit; font-size: smaller}
  36. pre.smallexample {font-size: smaller}
  37. pre.smallformat {font-family: inherit; font-size: smaller}
  38. pre.smalllisp {font-size: smaller}
  39. span.nocodebreak {white-space:nowrap}
  40. span.nolinebreak {white-space:nowrap}
  41. span.roman {font-family:serif; font-weight:normal}
  42. span.sansserif {font-family:sans-serif; font-weight:normal}
  43. ul.no-bullet {list-style: none}
  44. -->
  45. </style>
  46. </head>
  47. <body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
  48. <a name="Guard-Macros"></a>
  49. <div class="header">
  50. <p>
  51. Next: <a href="Files.html#Files" accesskey="n" rel="next">Files</a>, Previous: <a href="Line-Numbering.html#Line-Numbering" accesskey="p" rel="prev">Line Numbering</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
  52. </div>
  53. <hr>
  54. <a name="The-Multiple_002dInclude-Optimization"></a>
  55. <h2 class="unnumbered">The Multiple-Include Optimization</h2>
  56. <a name="index-guard-macros"></a>
  57. <a name="index-controlling-macros"></a>
  58. <a name="index-multiple_002dinclude-optimization"></a>
  59. <p>Header files are often of the form
  60. </p>
  61. <div class="smallexample">
  62. <pre class="smallexample">#ifndef FOO
  63. #define FOO
  64. &hellip;
  65. #endif
  66. </pre></div>
  67. <p>to prevent the compiler from processing them more than once. The
  68. preprocessor notices such header files, so that if the header file
  69. appears in a subsequent <code>#include</code> directive and <code>FOO</code> is
  70. defined, then it is ignored and it doesn&rsquo;t preprocess or even re-open
  71. the file a second time. This is referred to as the <em>multiple
  72. include optimization</em>.
  73. </p>
  74. <p>Under what circumstances is such an optimization valid? If the file
  75. were included a second time, it can only be optimized away if that
  76. inclusion would result in no tokens to return, and no relevant
  77. directives to process. Therefore the current implementation imposes
  78. requirements and makes some allowances as follows:
  79. </p>
  80. <ol>
  81. <li> There must be no tokens outside the controlling <code>#if</code>-<code>#endif</code>
  82. pair, but whitespace and comments are permitted.
  83. </li><li> There must be no directives outside the controlling directive pair, but
  84. the <em>null directive</em> (a line containing nothing other than a single
  85. &lsquo;<samp>#</samp>&rsquo; and possibly whitespace) is permitted.
  86. </li><li> The opening directive must be of the form
  87. <div class="smallexample">
  88. <pre class="smallexample">#ifndef FOO
  89. </pre></div>
  90. <p>or
  91. </p>
  92. <div class="smallexample">
  93. <pre class="smallexample">#if !defined FOO [equivalently, #if !defined(FOO)]
  94. </pre></div>
  95. </li><li> In the second form above, the tokens forming the <code>#if</code> expression
  96. must have come directly from the source file&mdash;no macro expansion must
  97. have been involved. This is because macro definitions can change, and
  98. tracking whether or not a relevant change has been made is not worth the
  99. implementation cost.
  100. </li><li> There can be no <code>#else</code> or <code>#elif</code> directives at the outer
  101. conditional block level, because they would probably contain something
  102. of interest to a subsequent pass.
  103. </li></ol>
  104. <p>First, when pushing a new file on the buffer stack,
  105. <code>_stack_include_file</code> sets the controlling macro <code>mi_cmacro</code> to
  106. <code>NULL</code>, and sets <code>mi_valid</code> to <code>true</code>. This indicates
  107. that the preprocessor has not yet encountered anything that would
  108. invalidate the multiple-include optimization. As described in the next
  109. few paragraphs, these two variables having these values effectively
  110. indicates top-of-file.
  111. </p>
  112. <p>When about to return a token that is not part of a directive,
  113. <code>_cpp_lex_token</code> sets <code>mi_valid</code> to <code>false</code>. This
  114. enforces the constraint that tokens outside the controlling conditional
  115. block invalidate the optimization.
  116. </p>
  117. <p>The <code>do_if</code>, when appropriate, and <code>do_ifndef</code> directive
  118. handlers pass the controlling macro to the function
  119. <code>push_conditional</code>. cpplib maintains a stack of nested conditional
  120. blocks, and after processing every opening conditional this function
  121. pushes an <code>if_stack</code> structure onto the stack. In this structure
  122. it records the controlling macro for the block, provided there is one
  123. and we&rsquo;re at top-of-file (as described above). If an <code>#elif</code> or
  124. <code>#else</code> directive is encountered, the controlling macro for that
  125. block is cleared to <code>NULL</code>. Otherwise, it survives until the
  126. <code>#endif</code> closing the block, upon which <code>do_endif</code> sets
  127. <code>mi_valid</code> to true and stores the controlling macro in
  128. <code>mi_cmacro</code>.
  129. </p>
  130. <p><code>_cpp_handle_directive</code> clears <code>mi_valid</code> when processing any
  131. directive other than an opening conditional and the null directive.
  132. With this, and requiring top-of-file to record a controlling macro, and
  133. no <code>#else</code> or <code>#elif</code> for it to survive and be copied to
  134. <code>mi_cmacro</code> by <code>do_endif</code>, we have enforced the absence of
  135. directives outside the main conditional block for the optimization to be
  136. on.
  137. </p>
  138. <p>Note that whilst we are inside the conditional block, <code>mi_valid</code> is
  139. likely to be reset to <code>false</code>, but this does not matter since
  140. the closing <code>#endif</code> restores it to <code>true</code> if appropriate.
  141. </p>
  142. <p>Finally, since <code>_cpp_lex_direct</code> pops the file off the buffer stack
  143. at <code>EOF</code> without returning a token, if the <code>#endif</code> directive
  144. was not followed by any tokens, <code>mi_valid</code> is <code>true</code> and
  145. <code>_cpp_pop_file_buffer</code> remembers the controlling macro associated
  146. with the file. Subsequent calls to <code>stack_include_file</code> result in
  147. no buffer being pushed if the controlling macro is defined, effecting
  148. the optimization.
  149. </p>
  150. <p>A quick word on how we handle the
  151. </p>
  152. <div class="smallexample">
  153. <pre class="smallexample">#if !defined FOO
  154. </pre></div>
  155. <p>case. <code>_cpp_parse_expr</code> and <code>parse_defined</code> take steps to see
  156. whether the three stages &lsquo;<samp>!</samp>&rsquo;, &lsquo;<samp>defined-expression</samp>&rsquo; and
  157. &lsquo;<samp>end-of-directive</samp>&rsquo; occur in order in a <code>#if</code> expression. If
  158. so, they return the guard macro to <code>do_if</code> in the variable
  159. <code>mi_ind_cmacro</code>, and otherwise set it to <code>NULL</code>.
  160. <code>enter_macro_context</code> sets <code>mi_valid</code> to false, so if a macro
  161. was expanded whilst parsing any part of the expression, then the
  162. top-of-file test in <code>push_conditional</code> fails and the optimization
  163. is turned off.
  164. </p>
  165. <hr>
  166. <div class="header">
  167. <p>
  168. Next: <a href="Files.html#Files" accesskey="n" rel="next">Files</a>, Previous: <a href="Line-Numbering.html#Line-Numbering" accesskey="p" rel="prev">Line Numbering</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
  169. </div>
  170. </body>
  171. </html>