Source file inclusion
지시문 바로 다음 줄에서 현재 소스 파일에 다른 소스 파일을 포함합니다.
목차 |
구문
#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) | (C++17부터) | |||||||
__has_include
(
string-literal
)
__has_include
(
<
h-pp-tokens
>
)
|
(5) | (C++17부터) | |||||||
| new-line | - | 개행 문자 |
| h-char-sequence | - |
하나 이상의
h-char
로 구성된 시퀀스. 다음 중 어느 것의 등장도 구현 정의 의미를 가진 조건부 지원됩니다:
|
| h-char | - | 소스 문자 집합 (C++23 이전) 번역 문자 집합 (C++23 이후) 의 구성원 중 개행과 > 를 제외한 모든 문자 |
| q-char-sequence | - |
하나 이상의
q-char
로 구성된 시퀀스. 다음 중 어느 것의 등장도 구현 정의 의미를 가진 조건부 지원됩니다:
|
| q-char | - | 소스 문자 집합 (C++23 이전) 번역 문자 집합 (C++23 이후) 의 구성원 중 개행과 " 를 제외한 모든 문자 |
| pp-tokens | - | 하나 이상의 전처리 토큰 으로 구성된 시퀀스 |
| string-literal | - | 문자열 리터럴 |
| h-pp-tokens | - | 전처리 토큰 중 > 를 제외한 하나 이상의 시퀀스 |
설명
include
이후의 전처리 토큰들은 일반 텍스트에서와 동일하게 처리됩니다(즉, 현재 매크로 이름으로 정의된 각 식별자는 해당 전처리 토큰들의 대체 목록으로 교체됩니다).
- 이러한 지시문이 #include 지시문의 구문 요구사항을 충족하지 않는 경우 프로그램은 ill-formed입니다.
-
그렇지 않으면,
__has_include표현식은 소스 파일 검색이 성공하면 1 로 평가되고, 검색이 실패하면 0 로 평가됩니다.
|
header-name
으로 식별되는 헤더(즉,
|
(C++20부터) |
__has_include
는
#if
와
#elif
표현식 내에서 확장될 수 있습니다. 이것은
#ifdef
,
#ifndef
,
#elifdef
,
#elifndef
(C++23부터)
그리고
defined
에 의해 정의된 매크로로 취급되지만, 다른 곳에서는 사용할 수 없습니다.
참고 사항
일반적인 구현은 표준 포함 디렉토리에서만 구문 (1) 을 검색합니다. 표준 C++ 라이브러리와 표준 C 라이브러리는 이러한 표준 포함 디렉토리에 암묵적으로 포함됩니다. 표준 포함 디렉토리는 일반적으로 사용자가 컴파일러 옵션을 통해 제어할 수 있습니다.
구문 (2) 의 의도는 구현에 의해 제어되지 않는 파일들을 검색하는 것입니다. 일반적인 구현에서는 현재 파일이 위치한 디렉토리를 먼저 검색한 후 (1) 으로 폴백(fallback)합니다.
파일이 포함되면, 해당 파일은 번역 단계 1-4에 의해 처리되며, 여기에는 구현에서 정의된 중첩 한계까지 재귀적으로 중첩된 #include 지시문의 확장이 포함될 수 있습니다. 동일한 파일의 반복적인 포함과 파일이 자신을 (아마도 전이적으로) 포함할 때의 무한 재귀를 방지하기 위해 헤더 가드 가 일반적으로 사용됩니다: 전체 헤더가 다음과 같이 감싸집니다
#ifndef FOO_H_INCLUDED /* any name uniquely mapped to file name */ #define FOO_H_INCLUDED // contents of the file are here #endif
많은 컴파일러는 비표준 pragma #pragma once 도 유사한 효과로 구현합니다: 동일한 파일(파일 식별은 OS별 방식으로 결정됨)이 이미 포함된 경우 파일 처리를 비활성화합니다.
q-char-sequence 또는 h-char-sequence 에서 이스케이프 시퀀스와 유사한 문자 시퀀스는 구현에 따라 오류가 발생하거나, 해당 이스케이프 시퀀스에 대응하는 문자로 해석되거나, 완전히 다른 의미를 가질 수 있습니다.
__has_include
의 결과가
1
인 것은 지정된 이름을 가진 헤더나 소스 파일이 존재한다는 의미만을 가집니다. 이는 해당 헤더나 소스 파일이 포함될 때 오류를 발생시키지 않거나 유용한 내용을 포함할 것임을 보장하지 않습니다. 예를 들어, C++14와 C++17 모드를 모두 지원하는 C++ 구현체에서(그리고 C++14 모드에서 규격 확장으로
__has_include
를 제공하는 경우),
__has_include
(
<
optional
>
)
가 C++14 모드에서
1
일 수 있지만, 실제로
#include <optional>
는 오류를 발생시킬 수 있습니다.
예제
#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'; }
출력:
<optional> is present op = -1 op = 42
결함 보고서
다음 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 787 | C++98 |
이스케이프 시퀀스가
q-char-sequence 또는 h-char-sequence 내에 존재할 경우 동작이 정의되지 않음 |
조건부 지원됨 |
참고 항목
**번역 설명:** - "Resource inclusion" → "리소스 포함" (C++ 표준 용어 유지) - "(since C++26)" → "(C++26부터)" (표준 버전 표기 방식 통일) - HTML 태그, 속성, 클래스명은 원본 그대로 유지 - C++ 관련 용어는 번역하지 않고 원문 유지| C++ 표준 라이브러리 헤더 파일 목록 | |
|
C 문서
for
소스 파일 포함
|