261 lines
17 KiB
Markdown
261 lines
17 KiB
Markdown
[cpp.pre]
|
||
|
||
# 15 Preprocessing directives [[cpp]](./#cpp)
|
||
|
||
## 15.1 Preamble [cpp.pre]
|
||
|
||
[preprocessing-file:](#nt:preprocessing-file "15.1 Preamble [cpp.pre]")
|
||
[*group*](#nt:group "15.1 Preamble [cpp.pre]")opt
|
||
[*module-file*](#nt:module-file "15.1 Preamble [cpp.pre]")
|
||
|
||
[module-file:](#nt:module-file "15.1 Preamble [cpp.pre]")
|
||
[*pp-global-module-fragment*](#nt:pp-global-module-fragment "15.1 Preamble [cpp.pre]")opt [*pp-module*](cpp.module#nt:pp-module "15.5 Module directive [cpp.module]") [*group*](#nt:group "15.1 Preamble [cpp.pre]")opt [*pp-private-module-fragment*](#nt:pp-private-module-fragment "15.1 Preamble [cpp.pre]")opt
|
||
|
||
[pp-global-module-fragment:](#nt:pp-global-module-fragment "15.1 Preamble [cpp.pre]")
|
||
module ; [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]") [*group*](#nt:group "15.1 Preamble [cpp.pre]")opt
|
||
|
||
[pp-private-module-fragment:](#nt:pp-private-module-fragment "15.1 Preamble [cpp.pre]")
|
||
module : private ; [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]") [*group*](#nt:group "15.1 Preamble [cpp.pre]")opt
|
||
|
||
[group:](#nt:group "15.1 Preamble [cpp.pre]")
|
||
[*group-part*](#nt:group-part "15.1 Preamble [cpp.pre]")
|
||
[*group*](#nt:group "15.1 Preamble [cpp.pre]") [*group-part*](#nt:group-part "15.1 Preamble [cpp.pre]")
|
||
|
||
[group-part:](#nt:group-part "15.1 Preamble [cpp.pre]")
|
||
[*control-line*](#nt:control-line "15.1 Preamble [cpp.pre]")
|
||
[*if-section*](#nt:if-section "15.1 Preamble [cpp.pre]")
|
||
[*text-line*](#nt:text-line "15.1 Preamble [cpp.pre]")
|
||
# [*conditionally-supported-directive*](#nt:conditionally-supported-directive "15.1 Preamble [cpp.pre]")
|
||
|
||
[control-line:](#nt:control-line "15.1 Preamble [cpp.pre]")
|
||
# include [*pp-tokens*](#nt:pp-tokens "15.1 Preamble [cpp.pre]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
[*pp-import*](cpp.import#nt:pp-import "15.6 Header unit importation [cpp.import]")
|
||
# embed [*pp-tokens*](#nt:pp-tokens "15.1 Preamble [cpp.pre]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
# define [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*replacement-list*](#nt:replacement-list "15.1 Preamble [cpp.pre]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
# define [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*lparen*](#nt:lparen "15.1 Preamble [cpp.pre]") [*identifier-list*](#nt:identifier-list "15.1 Preamble [cpp.pre]")opt ) [*replacement-list*](#nt:replacement-list "15.1 Preamble [cpp.pre]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
# define [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*lparen*](#nt:lparen "15.1 Preamble [cpp.pre]") ... ) [*replacement-list*](#nt:replacement-list "15.1 Preamble [cpp.pre]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
# define [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*lparen*](#nt:lparen "15.1 Preamble [cpp.pre]") [*identifier-list*](#nt:identifier-list "15.1 Preamble [cpp.pre]") , ... ) [*replacement-list*](#nt:replacement-list "15.1 Preamble [cpp.pre]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
# undef [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
# line [*pp-tokens*](#nt:pp-tokens "15.1 Preamble [cpp.pre]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
# error [*pp-tokens*](#nt:pp-tokens "15.1 Preamble [cpp.pre]")opt [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
# warning [*pp-tokens*](#nt:pp-tokens "15.1 Preamble [cpp.pre]")opt [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
# pragma [*pp-tokens*](#nt:pp-tokens "15.1 Preamble [cpp.pre]")opt [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
# [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
|
||
[if-section:](#nt:if-section "15.1 Preamble [cpp.pre]")
|
||
[*if-group*](#nt:if-group "15.1 Preamble [cpp.pre]") [*elif-groups*](#nt:elif-groups "15.1 Preamble [cpp.pre]")opt [*else-group*](#nt:else-group "15.1 Preamble [cpp.pre]")opt [*endif-line*](#nt:endif-line "15.1 Preamble [cpp.pre]")
|
||
|
||
[if-group:](#nt:if-group "15.1 Preamble [cpp.pre]")
|
||
# if [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]") [*group*](#nt:group "15.1 Preamble [cpp.pre]")opt
|
||
# ifdef [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]") [*group*](#nt:group "15.1 Preamble [cpp.pre]")opt
|
||
# ifndef [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]") [*group*](#nt:group "15.1 Preamble [cpp.pre]")opt
|
||
|
||
[elif-groups:](#nt:elif-groups "15.1 Preamble [cpp.pre]")
|
||
[*elif-group*](#nt:elif-group "15.1 Preamble [cpp.pre]") [*elif-groups*](#nt:elif-groups "15.1 Preamble [cpp.pre]")opt
|
||
|
||
[elif-group:](#nt:elif-group "15.1 Preamble [cpp.pre]")
|
||
# elif [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]") [*group*](#nt:group "15.1 Preamble [cpp.pre]")opt
|
||
# elifdef [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]") [*group*](#nt:group "15.1 Preamble [cpp.pre]")opt
|
||
# elifndef [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]") [*group*](#nt:group "15.1 Preamble [cpp.pre]")opt
|
||
|
||
[else-group:](#nt:else-group "15.1 Preamble [cpp.pre]")
|
||
# else [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]") [*group*](#nt:group "15.1 Preamble [cpp.pre]")opt
|
||
|
||
[endif-line:](#nt:endif-line "15.1 Preamble [cpp.pre]")
|
||
# endif [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
|
||
[text-line:](#nt:text-line "15.1 Preamble [cpp.pre]")
|
||
[*pp-tokens*](#nt:pp-tokens "15.1 Preamble [cpp.pre]")opt [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
|
||
[conditionally-supported-directive:](#nt:conditionally-supported-directive "15.1 Preamble [cpp.pre]")
|
||
[*pp-tokens*](#nt:pp-tokens "15.1 Preamble [cpp.pre]") [*new-line*](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
|
||
[lparen:](#nt:lparen "15.1 Preamble [cpp.pre]")
|
||
a ( character not immediately preceded by whitespace
|
||
|
||
[identifier-list:](#nt:identifier-list "15.1 Preamble [cpp.pre]")
|
||
[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")
|
||
[*identifier-list*](#nt:identifier-list "15.1 Preamble [cpp.pre]") , [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")
|
||
|
||
[replacement-list:](#nt:replacement-list "15.1 Preamble [cpp.pre]")
|
||
[*pp-tokens*](#nt:pp-tokens "15.1 Preamble [cpp.pre]")opt
|
||
|
||
[pp-tokens:](#nt:pp-tokens "15.1 Preamble [cpp.pre]")
|
||
[*preprocessing-token*](lex.pptoken#nt:preprocessing-token "5.5 Preprocessing tokens [lex.pptoken]") [*pp-tokens*](#nt:pp-tokens "15.1 Preamble [cpp.pre]")opt
|
||
|
||
[embed-parameter-seq:](#nt:embed-parameter-seq "15.1 Preamble [cpp.pre]")
|
||
[*embed-parameter*](#nt:embed-parameter "15.1 Preamble [cpp.pre]") [*embed-parameter-seq*](#nt:embed-parameter-seq "15.1 Preamble [cpp.pre]")opt
|
||
|
||
[embed-parameter:](#nt:embed-parameter "15.1 Preamble [cpp.pre]")
|
||
[*embed-standard-parameter*](#nt:embed-standard-parameter "15.1 Preamble [cpp.pre]")
|
||
[*embed-prefixed-parameter*](#nt:embed-prefixed-parameter "15.1 Preamble [cpp.pre]")
|
||
|
||
[embed-standard-parameter:](#nt:embed-standard-parameter "15.1 Preamble [cpp.pre]")
|
||
limit ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1 Preamble [cpp.pre]") )
|
||
prefix ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1 Preamble [cpp.pre]")opt )
|
||
suffix ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1 Preamble [cpp.pre]")opt )
|
||
if_empty ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1 Preamble [cpp.pre]")opt )
|
||
|
||
[embed-prefixed-parameter:](#nt:embed-prefixed-parameter "15.1 Preamble [cpp.pre]")
|
||
[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") :: [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")
|
||
[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") :: [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1 Preamble [cpp.pre]")opt )
|
||
|
||
[pp-balanced-token-seq:](#nt:pp-balanced-token-seq "15.1 Preamble [cpp.pre]")
|
||
[*pp-balanced-token*](#nt:pp-balanced-token "15.1 Preamble [cpp.pre]") [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1 Preamble [cpp.pre]")opt
|
||
|
||
[pp-balanced-token:](#nt:pp-balanced-token "15.1 Preamble [cpp.pre]")
|
||
( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1 Preamble [cpp.pre]")opt )
|
||
[ [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1 Preamble [cpp.pre]")opt ]
|
||
{ [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1 Preamble [cpp.pre]")opt }
|
||
any pp-token except:
|
||
parenthesis (U+0028 left parenthesis and U+0029 right parenthesis),
|
||
bracket (U+005b left square bracket and U+005d right square bracket), or
|
||
brace (U+007b left curly bracket and U+007d right curly bracket).
|
||
|
||
[new-line:](#nt:new-line "15.1 Preamble [cpp.pre]")
|
||
the new-line character
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L176)
|
||
|
||
A [*preprocessing directive*](#def:preprocessing_directive "15.1 Preamble [cpp.pre]") consists of a sequence of preprocessing tokens
|
||
that satisfies the following constraints:
|
||
At the start of translation phase 4,
|
||
the first preprocessing token in the sequence,
|
||
referred to as a [*directive-introducing token*](#def:token,directive-introducing "15.1 Preamble [cpp.pre]"),
|
||
begins with the first character in the source file
|
||
(optionally after whitespace containing no new-line characters) or
|
||
follows whitespace containing at least one new-line character,
|
||
and is
|
||
|
||
- [(1.1)](#1.1)
|
||
|
||
a # preprocessing token, or
|
||
|
||
- [(1.2)](#1.2)
|
||
|
||
an import preprocessing token
|
||
immediately followed on the same logical source line by a[*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]"),<,[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]"),[*string-literal*](lex.string#nt:string-literal "5.13.5 String literals [lex.string]"), or: preprocessing token, or
|
||
|
||
- [(1.3)](#1.3)
|
||
|
||
a module preprocessing token
|
||
immediately followed on the same logical source line by an[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]"),:, or; preprocessing token, or
|
||
|
||
- [(1.4)](#1.4)
|
||
|
||
an export preprocessing token
|
||
immediately followed on the same logical source line by
|
||
one of the two preceding forms[.](#1.sentence-1)
|
||
|
||
The last preprocessing token in the sequence is the first preprocessing token within the sequence that
|
||
is immediately followed by whitespace containing a new-line character[.](#1.sentence-2)[122](#footnote-122 "Thus, preprocessing directives are commonly called âlinesâ. These âlinesâ have no other syntactic significance, as all whitespace is equivalent except in certain situations during preprocessing (see the # character string literal creation operator in [cpp.stringize], for example).")
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
A new-line character ends the preprocessing directive even if it occurs
|
||
within what would otherwise be an invocation of a function-like macro[.](#1.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [1](#example-1)*: # // preprocessing directivemodule ; // preprocessing directiveexport module leftpad; // preprocessing directiveimport <string>; // preprocessing directiveexport import "squee"; // preprocessing directiveimport rightpad; // preprocessing directiveimport :part; // preprocessing directivemodule // not a preprocessing directive ; // not a preprocessing directiveexport // not a preprocessing directiveimport // not a preprocessing directive foo; // not a preprocessing directiveexport // not a preprocessing directiveimport foo; // preprocessing directive (ill-formed at phase 7)import :: // not a preprocessing directiveimport -> // not a preprocessing directive â *end example*]
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L255)
|
||
|
||
A sequence of preprocessing tokens is only a [*text-line*](#nt:text-line "15.1 Preamble [cpp.pre]") if it does not begin with a directive-introducing token[.](#2.sentence-1)
|
||
|
||
[*Example [2](#example-2)*: using module = int;module i; // not a [*text-line*](#nt:text-line "15.1 Preamble [cpp.pre]") and not a [*control-line*](#nt:control-line "15.1 Preamble [cpp.pre]")int foo() {return i;}
|
||
|
||
The example is not a valid [*preprocessing-file*](#nt:preprocessing-file "15.1 Preamble [cpp.pre]")[.](#2.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
A sequence of preprocessing tokens is only a [*conditionally-supported-directive*](#nt:conditionally-supported-directive "15.1 Preamble [cpp.pre]") if it does not begin with any of the directive names
|
||
appearing after a # in the syntax[.](#2.sentence-3)
|
||
|
||
A [*conditionally-supported-directive*](#nt:conditionally-supported-directive "15.1 Preamble [cpp.pre]") is
|
||
conditionally-supported withimplementation-defined
|
||
semantics[.](#2.sentence-4)
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L276)
|
||
|
||
If one of the [*pp-tokens*](#nt:pp-tokens "15.1 Preamble [cpp.pre]") of a #embed directive
|
||
(before macro replacement) is the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")limit, prefix, suffix, or if_empty and that [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is defined
|
||
as a macro ([[cpp.replace.general]](cpp.replace.general "15.7.1 General")), the program is ill-formed[.](#3.sentence-1)
|
||
|
||
Any [*embed-prefixed-parameter*](#nt:embed-prefixed-parameter "15.1 Preamble [cpp.pre]") is conditionally-supported,
|
||
with implementation-defined semantics[.](#3.sentence-2)
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L285)
|
||
|
||
At the start of phase 4 of translation,
|
||
the [*group*](#nt:group "15.1 Preamble [cpp.pre]") of a [*pp-global-module-fragment*](#nt:pp-global-module-fragment "15.1 Preamble [cpp.pre]") shall
|
||
contain neither a [*text-line*](#nt:text-line "15.1 Preamble [cpp.pre]") nor a [*pp-import*](cpp.import#nt:pp-import "15.6 Header unit importation [cpp.import]")[.](#4.sentence-1)
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L290)
|
||
|
||
When in a group that is skipped ([[cpp.cond]](cpp.cond "15.2 Conditional inclusion")), the directive
|
||
syntax is relaxed to allow any sequence of preprocessing tokens to occur between
|
||
the directive name and the following new-line character[.](#5.sentence-1)
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L295)
|
||
|
||
The only whitespace characters that shall appear
|
||
between preprocessing tokens
|
||
within a preprocessing directive
|
||
(from just after the directive-introducing token
|
||
through just before the terminating new-line character)
|
||
are space and horizontal-tab
|
||
(including spaces that have replaced comments
|
||
or possibly other whitespace characters
|
||
in translation phase 3)[.](#6.sentence-1)
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L306)
|
||
|
||
The implementation can
|
||
process and skip sections of source files conditionally,
|
||
include other source files,
|
||
import macros from header units,
|
||
and replace macros[.](#7.sentence-1)
|
||
|
||
These capabilities are called[*preprocessing*](#def:preprocessing "15.1 Preamble [cpp.pre]"),
|
||
because conceptually they occur
|
||
before translation of the resulting translation unit[.](#7.sentence-2)
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L317)
|
||
|
||
The preprocessing tokens within a preprocessing directive
|
||
are not subject to macro expansion unless otherwise stated[.](#8.sentence-1)
|
||
|
||
[*Example [3](#example-3)*:
|
||
|
||
In:#define EMPTY
|
||
EMPTY # include <file.h> the sequence of preprocessing tokens on the second line is *not* a preprocessing directive, because it does not begin with a # at the start of
|
||
translation phase 4, even though it will do so after the macro EMPTY has been replaced[.](#8.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[122)](#footnote-122)[122)](#footnoteref-122)
|
||
|
||
Thus,
|
||
preprocessing directives are commonly called âlinesâ[.](#footnote-122.sentence-1)
|
||
|
||
These âlinesâ have no other syntactic significance,
|
||
as all whitespace is equivalent except in certain situations
|
||
during preprocessing (see the# character string literal creation operator in [[cpp.stringize]](cpp.stringize "15.7.3 The # operator"), for example)[.](#footnote-122.sentence-2)
|