Guard-Macros.html 8.1 KB

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