Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/preprocessor/include"

From cppreference.com
m (Minor fix.)
m (fmt)
 
(2 intermediate revisions by 2 users not shown)
Line 4: Line 4:
  
 
===Syntax===
 
===Syntax===
 
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc | num=1 | {{ttb|#include <}} {{spar|h-char-sequence}} {{ttb|>}} {{spar|new-line}}}}
+
{{sdsc|num=1|{{ttb|#include <}} {{spar|h-char-sequence}} {{ttb|>}} {{spar|new-line}}}}
{{sdsc | num=2 | {{ttb|#include "}} {{spar|q-char-sequence}} {{ttb|"}} {{spar|new-line}}}}
+
{{sdsc|num=2|{{ttb|#include "}} {{spar|q-char-sequence}} {{ttb|"}} {{spar|new-line}}}}
{{sdsc | num=3 | {{ttb|#include}} {{spar|pp-tokens}} {{spar|new-line}}}}
+
{{sdsc|num=3|{{ttb|#include}} {{spar|pp-tokens}} {{spar|new-line}}}}
{{sdsc | num=4 | notes={{mark since c++17}} | {{ttb|__has_include}} {{ttb|(}} {{ttb|"}} {{spar|q-char-sequence}} {{ttb|"}} {{ttb|)}}<br>{{ttb|__has_include}} {{ttb|(}} {{ttb|&lt;}} {{spar|h-char-sequence}} {{ttb|&gt;}} {{ttb|)}}}}
+
{{sdsc|num=4|notes={{mark since c++17}}|{{ttb|__has_include}} {{ttb|(}} {{ttb|"}} {{spar|q-char-sequence}} {{ttb|"}} {{ttb|)}}<br>{{ttb|__has_include}} {{ttb|(}} {{ttb|&lt;}} {{spar|h-char-sequence}} {{ttb|&gt;}} {{ttb|)}}}}
{{sdsc | num=5 | notes={{mark since c++17}} | {{ttb|__has_include}} {{ttb|(}} {{spar|string-literal}} {{ttb|)}}<br>{{ttb|__has_include}} {{ttb|(}} {{ttb|&lt;}} {{spar|h-pp-tokens}} {{ttb|&gt;}} {{ttb|)}}
+
{{sdsc|num=5|notes={{mark since c++17}}|{{ttb|__has_include}} {{ttb|(}} {{spar|string-literal}} {{ttb|)}}<br>{{ttb|__has_include}} {{ttb|(}} {{ttb|&lt;}} {{spar|h-pp-tokens}} {{ttb|&gt;}} {{ttb|)}}
 
}}
 
}}
 
{{sdsc end}}
 
{{sdsc end}}
  
 
@1@ Searches for a header identified uniquely by {{spar|h-char-sequence}} and replaces the directive by the entire contents of the header.
 
@1@ Searches for a header identified uniquely by {{spar|h-char-sequence}} and replaces the directive by the entire contents of the header.
@2@ Searches for a source file identified by {{spar|q-char-sequence}} and replaces the directive by the entire contents of the source file. It may fallback to (1) and treat {{spar|q-char-sequence}} as a header identifier.
+
@2@ Searches for a source file identified by {{spar|q-char-sequence}} and replaces the directive by the entire contents of the source file. It may fallback to {{v|1}} and treat {{spar|q-char-sequence}} as a header identifier.
@3@ If neither (1) and (2) is matched, {{spar|pp-tokens}} will undergo macro replacement. The directive after replacement will be tried to match with (1) or (2) again.
+
@3@ If neither {{v|1}} nor {{v|2}} is matched, {{spar|pp-tokens}} will undergo macro replacement. The directive after replacement will be tried to match with {{v|1}} or {{v|2}} again.
 
@4@ Checks whether a header or source file is available for inclusion.
 
@4@ Checks whether a header or source file is available for inclusion.
@5@ If (4) is not matched, {{spar|h-pp-tokens}} will undergo macro replacement. The directive after replacement will be tried to match with (4) again.
+
@5@ If {{v|4}} is not matched, {{spar|h-pp-tokens}} will undergo macro replacement. The directive after replacement will be tried to match with {{v|4}} again.
  
 
{{par begin}}
 
{{par begin}}
{{par | {{spar|new-line}} | The new-line character }}
+
{{par|{{spar|new-line}}|The new-line character}}
{{par | {{spar|h-char-sequence}} | A sequence of one or more {{spar|h-char}}s }}
+
{{par|{{spar|h-char-sequence}}|A sequence of one or more {{spar|h-char}}s, where the appearance of any of the following is conditionally-supported with implementation-defined semantics:
{{par | {{spar|h-char}} | Any member of the {{rev inl|until=c++23|[[cpp/language/translation phases#Phase 5|source character set]]}}{{rev inl|since=c++23|[[cpp/language/charset#Translation character set|translation character set]]}} except new-line and {{tt|&gt;}} }}
+
* the character {{c|'}}
{{par | {{spar|q-char-sequence}} | A sequence of one or more {{spar|q-char}}s }}
+
* the character {{c|"}}
{{par | {{spar|q-char}} | Any member of the {{rev inl|until=c++23|[[cpp/language/translation phases#Phase 5|source character set]]}}{{rev inl|since=c++23|[[cpp/language/charset#Translation character set|translation character set]]}} except new-line and {{tt|"}} }}
+
* the character {{c|\}}
{{par | {{spar|pp-tokens}} | A sequence of one or more [[cpp/language/translation phases#Phase 3|preprocessing tokens]] }}
+
* the character sequence {{c|//}}
{{par | {{spar|string-literal}} | A [[cpp/language/string literal|string literal]] }}
+
* the character sequence {{c|/*}}}}
{{par | {{spar|h-pp-tokens}} | A sequence of one or more [[cpp/language/translation phases#Phase 3|preprocessing tokens]] except {{tt|&gt;}} }}
+
{{par|{{spar|h-char}}|Any member of the {{rev inl|until=c++23|[[cpp/language/translation phases#Phase 5|source character set]]}}{{rev inl|since=c++23|[[cpp/language/charset#Translation character set|translation character set]]}} except new-line and {{c|>}}}}
 +
{{par|{{spar|q-char-sequence}}|A sequence of one or more {{spar|q-char}}s, where the appearance of any of the following is conditionally-supported with implementation-defined semantics:
 +
* the character {{c|'}}
 +
* the character {{c|\}}
 +
* the character sequence {{c|//}}
 +
* the character sequence {{c|/*}}}}
 +
{{par|{{spar|q-char}}|Any member of the {{rev inl|until=c++23|[[cpp/language/translation phases#Phase 5|source character set]]}}{{rev inl|since=c++23|[[cpp/language/charset#Translation character set|translation character set]]}} except new-line and {{c|"}}}}
 +
{{par|{{spar|pp-tokens}}|A sequence of one or more [[cpp/language/translation phases#Phase 3|preprocessing tokens]]}}
 +
{{par|{{spar|string-literal}}|A [[cpp/language/string literal|string literal]]}}
 +
{{par|{{spar|h-pp-tokens}}|A sequence of one or more [[cpp/language/translation phases#Phase 3|preprocessing tokens]] except {{c|>}}}}
 
{{par end}}
 
{{par end}}
  
 
===Explanation===
 
===Explanation===
 
 
@1@ Searches a sequence of implementation-defined places for a header identified uniquely by {{spar|h-char-sequence}}, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.
 
@1@ Searches a sequence of implementation-defined places for a header identified uniquely by {{spar|h-char-sequence}}, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.
 
@2@ Causes the replacement of that directive by the entire contents of the source file identified by {{spar|q-char-sequence}}. The named source file is searched for in an implementation-defined
 
@2@ Causes the replacement of that directive by the entire contents of the source file identified by {{spar|q-char-sequence}}. The named source file is searched for in an implementation-defined
manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it reads syntax (1) with the identical contained sequence (including > characters, if any) from the original directive.
+
manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it reads syntax {{v|1}} with the identical contained sequence (including > characters, if any) from the original directive.
 
@3@ The preprocessing tokens after {{ttb|include}} in the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens). If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined. The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into
 
@3@ The preprocessing tokens after {{ttb|include}} in the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens). If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined. The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into
 
a single header name preprocessing token is implementation-defined.
 
a single header name preprocessing token is implementation-defined.
@4@ The header or source file identified by {{spar|h-char-sequence}} or {{spar|q-char-sequence}} is searched for as if that preprocessing token sequence were the {{spar|pp-tokens}} in syntax (3), except that no further macro expansion is performed. If such a directive would not satisfy the
+
@4@ The header or source file identified by {{spar|h-char-sequence}} or {{spar|q-char-sequence}} is searched for as if that preprocessing token sequence were the {{spar|pp-tokens}} in syntax {{v|3}}, except that no further macro expansion is performed. If such a directive would not satisfy the
syntactic requirements of an {{tt|#include}} directive, the program is ill-formed. The {{tt|__has_include}} expression evaluates to 1 if the search for the source file succeeds, and to 0 if the search fails.
+
syntactic requirements of an {{tt|#include}} directive, the program is ill-formed. The {{tt|__has_include}} expression evaluates to {{c|1}} if the search for the source file succeeds, and to {{c|0}} if the search fails.
 
@5@ This form is considered only if syntax (4) does not match, in which case the preprocessing tokens are processed just as in normal text.
 
@5@ This form is considered only if syntax (4) does not match, in which case the preprocessing tokens are processed just as in normal text.
  
Line 51: Line 58:
  
 
===Notes===
 
===Notes===
Typical implementations search only standard include directories for syntax (1). The standard C++ library and the standard C library are implicitly included in these standard include directories. The standard include directories usually can be controlled by the user through compiler options.
+
Typical implementations search only standard include directories for syntax {{v|1}}. The standard C++ library and the standard C library are implicitly included in these standard include directories. The standard include directories usually can be controlled by the user through compiler options.
  
The intent of syntax (2) is to search for the files that are not controlled by the implementation. Typical implementations first search the directory where the current file resides then falls back to (1).
+
The intent of syntax {{v|2}} is to search for the files that are not controlled by the implementation. Typical implementations first search the directory where the current file resides then falls back to {{v|1}}.
  
 
When a file is included, it is processed by [[cpp/language/translation phases|translation phases]] 1-4, which may include, recursively, expansion of the nested {{tt|#include}} directives, up to an implementation-defined nesting limit. To avoid repeated inclusion of the same file and endless recursion when a file includes itself, perhaps transitively, ''header guards'' are commonly used: the entire header is wrapped in  
 
When a file is included, it is processed by [[cpp/language/translation phases|translation phases]] 1-4, which may include, recursively, expansion of the nested {{tt|#include}} directives, up to an implementation-defined nesting limit. To avoid repeated inclusion of the same file and endless recursion when a file includes itself, perhaps transitively, ''header guards'' are commonly used: the entire header is wrapped in  
Line 63: Line 70:
 
}}
 
}}
 
Many compilers also implement the non-standard {{ltt|cpp/preprocessor/impl|pragma}} {{c|#pragma once}} with similar effects: it disables processing of a file if the same file (where file identity is determined in OS-specific way) has already been included.
 
Many compilers also implement the non-standard {{ltt|cpp/preprocessor/impl|pragma}} {{c|#pragma once}} with similar effects: it disables processing of a file if the same file (where file identity is determined in OS-specific way) has already been included.
 +
 +
A sequence of characters that resembles an escape sequence in {{spar|q-char-sequence}} or {{spar|h-char-sequence}} might result in an error, be interpreted as the character corresponding to the escape sequence, or have a completely different meaning, depending on the implementation.
  
 
A {{tt|__has_include}} result of {{c|1}} only means that a header or source file with the specified name exists. It does not mean that the header or source file, when included, would not cause an error or would contain anything useful. For example, on a C++ implementation that supports both C++14 and C++17 modes (and provides {{c|__has_include}} in its C++14 mode as a conforming extension), {{c|__has_include(<optional>)}} may be {{c|1}} in C++14 mode, but actually {{c|#include <optional>}} may cause an error.
 
A {{tt|__has_include}} result of {{c|1}} only means that a header or source file with the specified name exists. It does not mean that the header or source file, when included, would not cause an error or would contain anything useful. For example, on a C++ implementation that supports both C++14 and C++17 modes (and provides {{c|__has_include}} in its C++14 mode as a conforming extension), {{c|__has_include(<optional>)}} may be {{c|1}} in C++14 mode, but actually {{c|#include <optional>}} may cause an error.
Line 79: Line 88:
 
#  define has_optional 0
 
#  define has_optional 0
 
#  include <utility>
 
#  include <utility>
template<class V> class optional_t {
+
 
 +
template<class V>
 +
class optional_t
 +
{
 
     V v_{}; bool has_{false};
 
     V v_{}; bool has_{false};
  public:
+
public:
 
     optional_t() = default;
 
     optional_t() = default;
 
     optional_t(V&& v) : v_(v), has_{true} {}
 
     optional_t(V&& v) : v_(v), has_{true} {}
Line 110: Line 122:
 
op = 42
 
op = 42
 
}}
 
}}
 +
 +
===Defect reports===
 +
{{dr list begin}}
 +
{{dr list item|wg=cwg|dr=787|std=C++98|before=the behavior is undefined if an escape sequence is<br>resembled in {{spar|q-char-sequence}} or {{spar|h-char-sequence}}|after=it is conditionally-supported}}
 +
{{dr list end}}
  
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc | [[cpp/header | A list of C++ Standard Library header files]] }}
+
{{dsc|[[cpp/header|A list of C++ Standard Library header files]]}}
{{dsc see c | c/preprocessor/include | Source file inclusion | nomono=true}}
+
{{dsc see c|c/preprocessor/include|Source file inclusion|nomono=true}}
 
{{dsc end}}
 
{{dsc end}}
  
 
{{langlinks|ar|de|es|fr|it|ja|pl|pt|ru|zh}}
 
{{langlinks|ar|de|es|fr|it|ja|pl|pt|ru|zh}}

Latest revision as of 04:25, 9 July 2023

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

Includes other source file into current source file at the line immediately after the directive.

Contents

[edit] Syntax

#include < h-char-sequence > new-line (1)
#include " q-char-sequence " new-line (2)
#include pp-tokens new-line (3)
__has_include ( " q-char-sequence " )
__has_include ( < h-char-sequence > )
(4) (since C++17)
__has_include ( string-literal )
__has_include ( < h-pp-tokens > )
(5) (since C++17)
1) Searches for a header identified uniquely by h-char-sequence and replaces the directive by the entire contents of the header.
2) Searches for a source file identified by q-char-sequence and replaces the directive by the entire contents of the source file. It may fallback to (1) and treat q-char-sequence as a header identifier.
3) If neither (1) nor (2) is matched, pp-tokens will undergo macro replacement. The directive after replacement will be tried to match with (1) or (2) again.
4) Checks whether a header or source file is available for inclusion.
5) If (4) is not matched, h-pp-tokens will undergo macro replacement. The directive after replacement will be tried to match with (4) again.
new-line - The new-line character
h-char-sequence - A sequence of one or more h-chars, where the appearance of any of the following is conditionally-supported with implementation-defined semantics:
  • the character '
  • the character "
  • the character \
  • the character sequence //
  • the character sequence /*
h-char - Any member of the source character set(until C++23)translation character set(since C++23) except new-line and >
q-char-sequence - A sequence of one or more q-chars, where the appearance of any of the following is conditionally-supported with implementation-defined semantics:
  • the character '
  • the character \
  • the character sequence //
  • the character sequence /*
q-char - Any member of the source character set(until C++23)translation character set(since C++23) except new-line and "
pp-tokens - A sequence of one or more preprocessing tokens
string-literal - A string literal
h-pp-tokens - A sequence of one or more preprocessing tokens except >

[edit] Explanation

1) Searches a sequence of implementation-defined places for a header identified uniquely by h-char-sequence, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.
2) Causes the replacement of that directive by the entire contents of the source file identified by q-char-sequence. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it reads syntax (1) with the identical contained sequence (including > characters, if any) from the original directive.
3) The preprocessing tokens after include in the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens). If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined. The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single header name preprocessing token is implementation-defined.
4) The header or source file identified by h-char-sequence or q-char-sequence is searched for as if that preprocessing token sequence were the pp-tokens in syntax (3), except that no further macro expansion is performed. If such a directive would not satisfy the syntactic requirements of an #include directive, the program is ill-formed. The __has_include expression evaluates to 1 if the search for the source file succeeds, and to 0 if the search fails.
5) This form is considered only if syntax (4) does not match, in which case the preprocessing tokens are processed just as in normal text.

If the header identified by the header-name (i.e., < h-char-sequence > or " q-char-sequence ") denotes an importable header, it is implementation-defined whether the #include preprocessing directive is instead replaced by an import directive of the form

import header-name ; new-line

(since C++20)

__has_include can be expanded in the expression of #if and #elif. It is treated as a defined macro by #ifdef, #ifndef, #elifdef, #elifndef(since C++23) and defined but cannot be used anywhere else.

[edit] Notes

Typical implementations search only standard include directories for syntax (1). The standard C++ library and the standard C library are implicitly included in these standard include directories. The standard include directories usually can be controlled by the user through compiler options.

The intent of syntax (2) is to search for the files that are not controlled by the implementation. Typical implementations first search the directory where the current file resides then falls back to (1).

When a file is included, it is processed by translation phases 1-4, which may include, recursively, expansion of the nested #include directives, up to an implementation-defined nesting limit. To avoid repeated inclusion of the same file and endless recursion when a file includes itself, perhaps transitively, header guards are commonly used: the entire header is wrapped in

#ifndef FOO_H_INCLUDED /* any name uniquely mapped to file name */
#define FOO_H_INCLUDED
// contents of the file are here
#endif

Many compilers also implement the non-standard pragma #pragma once with similar effects: it disables processing of a file if the same file (where file identity is determined in OS-specific way) has already been included.

A sequence of characters that resembles an escape sequence in q-char-sequence or h-char-sequence might result in an error, be interpreted as the character corresponding to the escape sequence, or have a completely different meaning, depending on the implementation.

A __has_include result of 1 only means that a header or source file with the specified name exists. It does not mean that the header or source file, when included, would not cause an error or would contain anything useful. For example, on a C++ implementation that supports both C++14 and C++17 modes (and provides __has_include in its C++14 mode as a conforming extension), __has_include(<optional>) may be 1 in C++14 mode, but actually #include <optional> may cause an error.

[edit] Example

#if __has_include(<optional>)
#  include <optional>
#  define has_optional 1
   template<class T> using optional_t = std::optional<T>;
#elif __has_include(<experimental/optional>)
#  include <experimental/optional>
#  define has_optional -1
   template<class T> using optional_t = std::experimental::optional<T>;
#else
#  define has_optional 0
#  include <utility>
 
template<class V>
class optional_t
{
    V v_{}; bool has_{false};
public:
    optional_t() = default;
    optional_t(V&& v) : v_(v), has_{true} {}
    V value_or(V&& alt) const& { return has_ ? v_ : alt; }
    /*...*/
};
#endif
 
#include <iostream>
 
int main()
{
    if (has_optional > 0)
        std::cout << "<optional> is present\n";
    else if (has_optional < 0)
        std::cout << "<experimental/optional> is present\n";
    else
        std::cout << "<optional> is not present\n";
 
    optional_t<int> op;
    std::cout << "op = " << op.value_or(-1) << '\n';
    op = 42;
    std::cout << "op = " << op.value_or(-1) << '\n';
}

Output:

<optional> is present
op = -1
op = 42

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
CWG 787 C++98 the behavior is undefined if an escape sequence is
resembled in q-char-sequence or h-char-sequence
it is conditionally-supported

[edit] See also

A list of C++ Standard Library header files
C documentation for Source file inclusion