Namespaces
Variants

Source file inclusion

From cppreference.net

Включает другой исходный файл в текущий исходный файл на строке, непосредственно следующей за директивой.

Содержание

Синтаксис

#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) (начиная с C23)
__has_include ( string-literal )
__has_include ( < h-pp-tokens > )
(5) (начиная с C23)
1) Осуществляет поиск заголовка, однозначно идентифицируемого с помощью h-char-sequence и заменяет директиву всем содержимым этого заголовка.
2) Выполняет поиск исходного файла, идентифицированного q-char-sequence и заменяет директиву всем содержимым исходного файла. Может переключиться на (1) и обрабатывать q-char-sequence как идентификатор заголовка.
3) Если ни (1) , ни (2) не совпадают, pp-tokens подвергнутся макроподстановке. Директива после подстановки будет снова проверяться на соответствие с (1) или (2) .
4) Проверяет, доступен ли заголовочный или исходный файл для включения.
5) Если (4) не совпадает, h-pp-tokens подвергнутся макроподстановке. Директива после подстановки будет повторно проверяться на соответствие с (4) .
new-line - Символ новой строки
h-char-sequence - Последовательность одного или более h-char s, где появление любого из следующих вызывает неопределённое поведение:
  • символ '
  • символ "
  • символ \
  • последовательность символов //
  • последовательность символов /*
h-char - Любой элемент исходного набора символов кроме символа новой строки и >
q-char-sequence - Последовательность одного или более q-char s, где появление любого из следующих вызывает неопределённое поведение:
  • символ '
  • символ \
  • последовательность символов //
  • последовательность символов /*
q-char - Любой элемент исходного набора символов кроме символа новой строки и "
pp-tokens - Последовательность одного или более токенов препроцессора
string-literal - Строковый литерал
h-pp-tokens - Последовательность одного или более токенов препроцессора кроме >

Объяснение

1) Выполняет поиск файла, идентифицированного h-char-sequence способом, определяемым реализацией. Цель данного синтаксиса - поиск файлов, находящихся под контролем реализации. Типичные реализации выполняют поиск только в стандартных каталогах включения. Стандартная библиотека C неявно включается в эти стандартные каталоги включения. Стандартные каталоги включения обычно могут контролироваться пользователем через опции компилятора.
2) Выполняет поиск файла, идентифицированного q-char-sequence , способом, определяемым реализацией. Цель данного синтаксиса - поиск файлов, не контролируемых реализацией. Типичные реализации сначала ищут в директории, где находится текущий файл, и только если файл не найден, выполняют поиск в стандартных директориях включения, как в (1) .
3) Препроцессирующие токены после include в директиве обрабатываются так же, как в обычном тексте (т.е. каждое имя идентификатора, определённое в настоящее время как имя макроса, заменяется его списком замены препроцессирующих токенов). Директива, полученная после всех замен, должна соответствовать одной из двух предыдущих форм. Способ, которым последовательность препроцессирующих токенов между < и > парой препроцессирующих токенов или парой символов " объединяется в единый токен имени заголовка, определяется реализацией.
4) Заголовочный или исходный файл, идентифицируемый h-char-sequence или q-char-sequence , ищется таким образом, как если бы эта последовательность препроцессинговых токенов была pp-tokens в синтаксисе (3) , за исключением того, что дальнейшее макроподстановки не выполняются. Если такая директива не удовлетворяет синтаксическим требованиям директивы #include , программа является некорректной. Выражение __has_include вычисляется в 1 , если поиск исходного файла завершается успешно, и в 0 , если поиск завершается неудачно.
5) Эта форма рассматривается только в том случае, если синтаксис (4) не совпадает, и в этом случае токены препроцессора обрабатываются так же, как в обычном тексте.

В случае, если файл не найден, программа является некорректно сформированной.

__has_include может быть раскрыто в выражениях #if и #elif . Оно рассматривается как определенный макрос в #ifdef , #ifndef , #elifdef , #elifndef и defined , но не может использоваться где-либо еще.

(начиная с C23)

Примечания

Типичные реализации производят поиск только в стандартных каталогах включения для синтаксиса (1). Стандартная библиотека C неявно включена в эти стандартные каталоги включения. Стандартные каталоги включения обычно могут контролироваться пользователем через опции компилятора.

Назначение синтаксиса (2) — поиск файлов, не контролируемых реализацией. Типичные реализации сначала выполняют поиск в директории, где находится текущий файл, а затем переходят к (1) .

Когда файл включается, он обрабатывается фазами трансляции 1-4, что может включать, рекурсивно, раскрытие вложенных #include директив, до достижения определённого реализацией предела вложенности. Чтобы избежать повторного включения одного и того же файла и бесконечной рекурсии, когда файл включает себя, возможно транзитивно, обычно используются header guards : весь заголовочный файл оборачивается в

#ifndef FOO_H_INCLUDED /* any name uniquely mapped to file name */
#define FOO_H_INCLUDED
// содержимое файла находится здесь
#endif

Многие компиляторы также реализуют нестандартную pragma #pragma once с аналогичным эффектом: она отключает обработку файла, если тот же файл (где идентичность файла определяется специфичным для ОС способом) уже был включен.

Результат __has_include равный 1 означает только то, что заголовочный или исходный файл с указанным именем существует. Это не означает, что при включении этого заголовочного или исходного файла не возникнет ошибка или что он будет содержать что-либо полезное.

Пример

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
  • 6.4.7 Имена заголовков (стр: 69)
  • 6.10.1 Условное включение (стр: 165-169)
  • 6.10.2 Включение исходных файлов (стр: 169-170)
  • Стандарт C17 (ISO/IEC 9899:2018):
  • 6.10.2 Включение исходных файлов (стр: 119-120)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 6.10.2 Включение исходных файлов (стр: 164-166)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • 6.10.2 Включение исходных файлов (стр: 149-151)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
  • 3.8.2 Включение исходных файлов

Смотрите также

Список заголовочных файлов стандартной библиотеки C
Документация C++ для Включение исходных файлов