Source file inclusion
Incluye otro archivo fuente en el archivo fuente actual en la línea inmediatamente posterior a la directiva.
Contenidos |
Sintaxis
#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) | (desde C++17) | |||||||
__has_include
(
string-literal
)
__has_include
(
<
h-pp-tokens
>
)
|
(5) | (desde C++17) | |||||||
| new-line | - | El carácter de nueva línea |
| h-char-sequence | - |
Una secuencia de uno o más
h-char
s, donde la aparición de cualquiera de los siguientes es condicionalmente compatible con semántica definida por la implementación:
|
| h-char | - | Cualquier miembro del juego de caracteres fuente (hasta C++23) juego de caracteres de traducción (desde C++23) excepto nueva línea y > |
| q-char-sequence | - |
Una secuencia de uno o más
q-char
s, donde la aparición de cualquiera de los siguientes es condicionalmente compatible con semántica definida por la implementación:
|
| q-char | - | Cualquier miembro del juego de caracteres fuente (hasta C++23) juego de caracteres de traducción (desde C++23) excepto nueva línea y " |
| pp-tokens | - | Una secuencia de uno o más tokens de preprocesamiento |
| string-literal | - | Un literal de cadena |
| h-pp-tokens | - | Una secuencia de uno o más tokens de preprocesamiento excepto > |
Explicación
include
en la directiva se procesan exactamente como en texto normal (es decir, cada identificador actualmente definido como nombre de macro se reemplaza por su lista de reemplazo de tokens de preprocesamiento).
- Si dicha directiva no satisficiera los requisitos sintácticos de una #include directive, el programa está mal formado.
-
De lo contrario, la expresión
__has_includese evalúa como 1 si la búsqueda del archivo fuente tiene éxito, y como 0 si la búsqueda falla.
|
Si el encabezado identificado por el
header-name
(es decir,
|
(since C++20) |
__has_include
puede expandirse en la expresión de
#if
y
#elif
. Es tratado como una macro definida por
#ifdef
,
#ifndef
,
#elifdef
,
#elifndef
(desde C++23)
y
defined
pero no puede utilizarse en ningún otro lugar.
Notas
Las implementaciones típicas solo buscan en los directorios de inclusión estándar para la sintaxis (1) . La biblioteca estándar de C++ y la biblioteca estándar de C están implícitamente incluidas en estos directorios de inclusión estándar. Los directorios de inclusión estándar normalmente pueden ser controlados por el usuario mediante opciones del compilador.
La intención de la sintaxis (2) es buscar los archivos que no están controlados por la implementación. Las implementaciones típicas primero buscan en el directorio donde reside el archivo actual y luego recurren a (1) .
Cuando un archivo es incluido, es procesado por las fases de traducción 1-4, lo que puede incluir, recursivamente, la expansión de las directivas anidadas #include , hasta un límite de anidamiento definido por la implementación. Para evitar la inclusión repetida del mismo archivo y la recursión infinita cuando un archivo se incluye a sí mismo, quizás de forma transitiva, comúnmente se utilizan guardas de cabecera : todo el encabezado se envuelve en
#ifndef FOO_H_INCLUDED /* any name uniquely mapped to file name */ #define FOO_H_INCLUDED // contents of the file are here #endif
Muchos compiladores también implementan la no estándar pragma #pragma once con efectos similares: desactiva el procesamiento de un archivo si el mismo archivo (donde la identidad del archivo se determina de forma específica del sistema operativo) ya ha sido incluido.
Una secuencia de caracteres que se asemeje a una secuencia de escape en q-char-sequence o h-char-sequence podría resultar en un error, ser interpretada como el carácter correspondiente a la secuencia de escape, o tener un significado completamente diferente, dependiendo de la implementación.
Un resultado de
__has_include
de
1
solo significa que existe un archivo de cabecera o fuente con el nombre especificado. No significa que el archivo de cabecera o fuente, al ser incluido, no causaría un error o contendría algo útil. Por ejemplo, en una implementación de C++ que admite tanto el modo C++14 como C++17 (y proporciona
__has_include
en su modo C++14 como una extensión conforme),
__has_include
(
<
optional
>
)
puede ser
1
en modo C++14, pero en realidad
#include <optional>
puede causar un error.
Ejemplo
#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 template<class V> class optional_t { V v{}; bool has{}; public: optional_t() = default; optional_t(V&& v) : v(v), has{true} {} V value_or(V&& alt) const& { return has ? v : alt; } // etc. }; #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'; }
Salida:
<optional> is present op = -1 op = 42
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| CWG 787 | C++98 |
el comportamiento es indefinido si una secuencia de escape
se asemeja en q-char-sequence o h-char-sequence |
es condicionalmente soportado |
Véase también
| Una lista de archivos de cabecera de la Biblioteca Estándar de C++ | |
|
Documentación de C
para
Inclusión de archivos fuente
|