You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
7.7 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- Copyright (C) 1987-2018 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation. A copy of
the license is included in the
section entitled "GNU Free Documentation License".
This manual contains no Invariant Sections. The Front-Cover Texts are
(a) (see below), and the Back-Cover Texts are (b) (see below).
(a) The FSF's Front-Cover Text is:
A GNU Manual
(b) The FSF's Back-Cover Text is:
You have freedom to copy and modify this GNU Manual, like GNU
software. Copies published by the Free Software Foundation raise
funds for GNU development. -->
<!-- Created by GNU Texinfo 6.4, http://www.gnu.org/software/texinfo/ -->
<head>
<title>Computed Includes (The C Preprocessor)</title>
<meta name="description" content="Computed Includes (The C Preprocessor)">
<meta name="keywords" content="Computed Includes (The C Preprocessor)">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="index.html#Top" rel="start" title="Top">
<link href="Index-of-Directives.html#Index-of-Directives" rel="index" title="Index of Directives">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Header-Files.html#Header-Files" rel="up" title="Header Files">
<link href="Wrapper-Headers.html#Wrapper-Headers" rel="next" title="Wrapper Headers">
<link href="Alternatives-to-Wrapper-_0023ifndef.html#Alternatives-to-Wrapper-_0023ifndef" rel="prev" title="Alternatives to Wrapper #ifndef">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
blockquote.indentedblock {margin-right: 0em}
blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
blockquote.smallquotation {font-size: smaller}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
div.smalldisplay {margin-left: 3.2em}
div.smallexample {margin-left: 3.2em}
div.smalllisp {margin-left: 3.2em}
kbd {font-style: oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: inherit; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: inherit; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.nolinebreak {white-space: nowrap}
span.roman {font-family: initial; font-weight: normal}
span.sansserif {font-family: sans-serif; font-weight: normal}
ul.no-bullet {list-style: none}
-->
</style>
</head>
<body lang="en">
<a name="Computed-Includes"></a>
<div class="header">
<p>
Next: <a href="Wrapper-Headers.html#Wrapper-Headers" accesskey="n" rel="next">Wrapper Headers</a>, Previous: <a href="Alternatives-to-Wrapper-_0023ifndef.html#Alternatives-to-Wrapper-_0023ifndef" accesskey="p" rel="prev">Alternatives to Wrapper #ifndef</a>, Up: <a href="Header-Files.html#Header-Files" accesskey="u" rel="up">Header Files</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Index-of-Directives.html#Index-of-Directives" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<a name="Computed-Includes-1"></a>
<h3 class="section">2.6 Computed Includes</h3>
<a name="index-computed-includes"></a>
<a name="index-macros-in-include"></a>
<p>Sometimes it is necessary to select one of several different header
files to be included into your program. They might specify
configuration parameters to be used on different sorts of operating
systems, for instance. You could do this with a series of conditionals,
</p>
<div class="smallexample">
<pre class="smallexample">#if SYSTEM_1
# include &quot;system_1.h&quot;
#elif SYSTEM_2
# include &quot;system_2.h&quot;
#elif SYSTEM_3
&hellip;
#endif
</pre></div>
<p>That rapidly becomes tedious. Instead, the preprocessor offers the
ability to use a macro for the header name. This is called a
<em>computed include</em>. Instead of writing a header name as the direct
argument of &lsquo;<samp>#include</samp>&rsquo;, you simply put a macro name there instead:
</p>
<div class="smallexample">
<pre class="smallexample">#define SYSTEM_H &quot;system_1.h&quot;
&hellip;
#include SYSTEM_H
</pre></div>
<p><code>SYSTEM_H</code> will be expanded, and the preprocessor will look for
<samp>system_1.h</samp> as if the &lsquo;<samp>#include</samp>&rsquo; had been written that way
originally. <code>SYSTEM_H</code> could be defined by your Makefile with a
<samp>-D</samp> option.
</p>
<p>You must be careful when you define the macro. &lsquo;<samp>#define</samp>&rsquo; saves
tokens, not text. The preprocessor has no way of knowing that the macro
will be used as the argument of &lsquo;<samp>#include</samp>&rsquo;, so it generates
ordinary tokens, not a header name. This is unlikely to cause problems
if you use double-quote includes, which are close enough to string
constants. If you use angle brackets, however, you may have trouble.
</p>
<p>The syntax of a computed include is actually a bit more general than the
above. If the first non-whitespace character after &lsquo;<samp>#include</samp>&rsquo; is
not &lsquo;<samp>&quot;</samp>&rsquo; or &lsquo;<samp>&lt;</samp>&rsquo;, then the entire line is macro-expanded
like running text would be.
</p>
<p>If the line expands to a single string constant, the contents of that
string constant are the file to be included. CPP does not re-examine the
string for embedded quotes, but neither does it process backslash
escapes in the string. Therefore
</p>
<div class="smallexample">
<pre class="smallexample">#define HEADER &quot;a\&quot;b&quot;
#include HEADER
</pre></div>
<p>looks for a file named <samp>a\&quot;b</samp>. CPP searches for the file according
to the rules for double-quoted includes.
</p>
<p>If the line expands to a token stream beginning with a &lsquo;<samp>&lt;</samp>&rsquo; token
and including a &lsquo;<samp>&gt;</samp>&rsquo; token, then the tokens between the &lsquo;<samp>&lt;</samp>&rsquo; and
the first &lsquo;<samp>&gt;</samp>&rsquo; are combined to form the filename to be included.
Any whitespace between tokens is reduced to a single space; then any
space after the initial &lsquo;<samp>&lt;</samp>&rsquo; is retained, but a trailing space
before the closing &lsquo;<samp>&gt;</samp>&rsquo; is ignored. CPP searches for the file
according to the rules for angle-bracket includes.
</p>
<p>In either case, if there are any tokens on the line after the file name,
an error occurs and the directive is not processed. It is also an error
if the result of expansion does not match either of the two expected
forms.
</p>
<p>These rules are implementation-defined behavior according to the C
standard. To minimize the risk of different compilers interpreting your
computed includes differently, we recommend you use only a single
object-like macro which expands to a string constant. This will also
minimize confusion for people reading your program.
</p>
<hr>
<div class="header">
<p>
Next: <a href="Wrapper-Headers.html#Wrapper-Headers" accesskey="n" rel="next">Wrapper Headers</a>, Previous: <a href="Alternatives-to-Wrapper-_0023ifndef.html#Alternatives-to-Wrapper-_0023ifndef" accesskey="p" rel="prev">Alternatives to Wrapper #ifndef</a>, Up: <a href="Header-Files.html#Header-Files" accesskey="u" rel="up">Header Files</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Index-of-Directives.html#Index-of-Directives" title="Index" rel="index">Index</a>]</p>
</div>
</body>
</html>