Files
2025-10-25 03:02:53 +03:00

261 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[cpp.pre]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.1 Preamble [cpp.pre]
[preprocessing-file:](#nt:preprocessing-file "15.1Preamble[cpp.pre]")
[*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[*module-file*](#nt:module-file "15.1Preamble[cpp.pre]")
[module-file:](#nt:module-file "15.1Preamble[cpp.pre]")
[*pp-global-module-fragment*](#nt:pp-global-module-fragment "15.1Preamble[cpp.pre]")opt [*pp-module*](cpp.module#nt:pp-module "15.5Module directive[cpp.module]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt [*pp-private-module-fragment*](#nt:pp-private-module-fragment "15.1Preamble[cpp.pre]")opt
[pp-global-module-fragment:](#nt:pp-global-module-fragment "15.1Preamble[cpp.pre]")
module ; [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[pp-private-module-fragment:](#nt:pp-private-module-fragment "15.1Preamble[cpp.pre]")
module : private ; [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[group:](#nt:group "15.1Preamble[cpp.pre]")
[*group-part*](#nt:group-part "15.1Preamble[cpp.pre]")
[*group*](#nt:group "15.1Preamble[cpp.pre]") [*group-part*](#nt:group-part "15.1Preamble[cpp.pre]")
[group-part:](#nt:group-part "15.1Preamble[cpp.pre]")
[*control-line*](#nt:control-line "15.1Preamble[cpp.pre]")
[*if-section*](#nt:if-section "15.1Preamble[cpp.pre]")
[*text-line*](#nt:text-line "15.1Preamble[cpp.pre]")
# [*conditionally-supported-directive*](#nt:conditionally-supported-directive "15.1Preamble[cpp.pre]")
[control-line:](#nt:control-line "15.1Preamble[cpp.pre]")
# include [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
[*pp-import*](cpp.import#nt:pp-import "15.6Header unit importation[cpp.import]")
# embed [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*replacement-list*](#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](#nt:lparen "15.1Preamble[cpp.pre]") [*identifier-list*](#nt:identifier-list "15.1Preamble[cpp.pre]")opt ) [*replacement-list*](#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](#nt:lparen "15.1Preamble[cpp.pre]") ... ) [*replacement-list*](#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](#nt:lparen "15.1Preamble[cpp.pre]") [*identifier-list*](#nt:identifier-list "15.1Preamble[cpp.pre]") , ... ) [*replacement-list*](#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# undef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# line [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# error [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# warning [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# pragma [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
[if-section:](#nt:if-section "15.1Preamble[cpp.pre]")
[*if-group*](#nt:if-group "15.1Preamble[cpp.pre]") [*elif-groups*](#nt:elif-groups "15.1Preamble[cpp.pre]")opt [*else-group*](#nt:else-group "15.1Preamble[cpp.pre]")opt [*endif-line*](#nt:endif-line "15.1Preamble[cpp.pre]")
[if-group:](#nt:if-group "15.1Preamble[cpp.pre]")
# if [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
# ifdef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
# ifndef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[elif-groups:](#nt:elif-groups "15.1Preamble[cpp.pre]")
[*elif-group*](#nt:elif-group "15.1Preamble[cpp.pre]") [*elif-groups*](#nt:elif-groups "15.1Preamble[cpp.pre]")opt
[elif-group:](#nt:elif-group "15.1Preamble[cpp.pre]")
# elif [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
# elifdef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
# elifndef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[else-group:](#nt:else-group "15.1Preamble[cpp.pre]")
# else [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[endif-line:](#nt:endif-line "15.1Preamble[cpp.pre]")
# endif [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
[text-line:](#nt:text-line "15.1Preamble[cpp.pre]")
[*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
[conditionally-supported-directive:](#nt:conditionally-supported-directive "15.1Preamble[cpp.pre]")
[*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
[lparen:](#nt:lparen "15.1Preamble[cpp.pre]")
a ( character not immediately preceded by whitespace
[identifier-list:](#nt:identifier-list "15.1Preamble[cpp.pre]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[*identifier-list*](#nt:identifier-list "15.1Preamble[cpp.pre]") , [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[replacement-list:](#nt:replacement-list "15.1Preamble[cpp.pre]")
[*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt
[pp-tokens:](#nt:pp-tokens "15.1Preamble[cpp.pre]")
[*preprocessing-token*](lex.pptoken#nt:preprocessing-token "5.5Preprocessing tokens[lex.pptoken]") [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt
[embed-parameter-seq:](#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")
[*embed-parameter*](#nt:embed-parameter "15.1Preamble[cpp.pre]") [*embed-parameter-seq*](#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")opt
[embed-parameter:](#nt:embed-parameter "15.1Preamble[cpp.pre]")
[*embed-standard-parameter*](#nt:embed-standard-parameter "15.1Preamble[cpp.pre]")
[*embed-prefixed-parameter*](#nt:embed-prefixed-parameter "15.1Preamble[cpp.pre]")
[embed-standard-parameter:](#nt:embed-standard-parameter "15.1Preamble[cpp.pre]")
limit ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") )
prefix ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
suffix ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
if_empty ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
[embed-prefixed-parameter:](#nt:embed-prefixed-parameter "15.1Preamble[cpp.pre]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") :: [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") :: [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
[pp-balanced-token-seq:](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")
[*pp-balanced-token*](#nt:pp-balanced-token "15.1Preamble[cpp.pre]") [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt
[pp-balanced-token:](#nt:pp-balanced-token "15.1Preamble[cpp.pre]")
( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
[ [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt ]
{ [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[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.1Preamble[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.1Preamble[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.1Preamble[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.6Header names[lex.header]"),<,[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]"),[*string-literal*](lex.string#nt:string-literal "5.13.5String 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.11Identifiers[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.1Preamble[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.1Preamble[cpp.pre]") and not a [*control-line*](#nt:control-line "15.1Preamble[cpp.pre]")int foo() {return i;}
The example is not a valid [*preprocessing-file*](#nt:preprocessing-file "15.1Preamble[cpp.pre]")[.](#2.sentence-2)
— *end example*]
A sequence of preprocessing tokens is only a [*conditionally-supported-directive*](#nt:conditionally-supported-directive "15.1Preamble[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.1Preamble[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.1Preamble[cpp.pre]") of a #embed directive
(before macro replacement) is the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")limit, prefix, suffix, or if_empty and that [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is defined
as a macro ([[cpp.replace.general]](cpp.replace.general "15.7.1General")), the program is ill-formed[.](#3.sentence-1)
Any [*embed-prefixed-parameter*](#nt:embed-prefixed-parameter "15.1Preamble[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.1Preamble[cpp.pre]") of a [*pp-global-module-fragment*](#nt:pp-global-module-fragment "15.1Preamble[cpp.pre]") shall
contain neither a [*text-line*](#nt:text-line "15.1Preamble[cpp.pre]") nor a [*pp-import*](cpp.import#nt:pp-import "15.6Header 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.2Conditional 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.1Preamble[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.3The # operator"), for example)[.](#footnote-122.sentence-2)