Namespaces
Variants

Source file inclusion

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
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
Special member functions
Templates
Miscellaneous

지시문 바로 다음 줄에서 현재 소스 파일에 다른 소스 파일을 포함합니다.

목차

구문

#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부터)
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 로 구성된 시퀀스. 다음 중 어느 것의 등장도 구현 정의 의미를 가진 조건부 지원됩니다:
  • 문자 '
  • 문자 "
  • 문자 \
  • 문자 시퀀스 //
  • 문자 시퀀스 /*
h-char - 소스 문자 집합 (C++23 이전) 번역 문자 집합 (C++23 이후) 의 구성원 중 개행과 > 를 제외한 모든 문자
q-char-sequence - 하나 이상의 q-char 로 구성된 시퀀스. 다음 중 어느 것의 등장도 구현 정의 의미를 가진 조건부 지원됩니다:
  • 문자 '
  • 문자 \
  • 문자 시퀀스 //
  • 문자 시퀀스 /*
q-char - 소스 문자 집합 (C++23 이전) 번역 문자 집합 (C++23 이후) 의 구성원 중 개행과 " 를 제외한 모든 문자
pp-tokens - 하나 이상의 전처리 토큰 으로 구성된 시퀀스
string-literal - 문자열 리터럴
h-pp-tokens - 전처리 토큰 > 를 제외한 하나 이상의 시퀀스

설명

1) h-char-sequence 로 고유하게 식별되는 헤더를 위한 위치들의 시퀀스를 검색하고, 해당 지시문을 헤더 전체 내용으로 대체하도록 합니다. 위치들이 지정되거나 헤더가 식별되는 방식은 구현에 따라 정의됩니다.
2) 해당 지시문을 q-char-sequence 로 식별된 소스 파일 전체 내용으로 대체합니다. 명명된 소스 파일은 구현에서 정의된 방식으로 검색됩니다.
이 검색이 지원되지 않거나 검색이 실패할 경우, 해당 지시문은 원래 지시문의 동일한 포함 시퀀스(있는 경우 > 문자 포함)를 가진 구문 (1) 으로 재처리됩니다.
3) 지시문에서 include 이후의 전처리 토큰들은 일반 텍스트에서와 동일하게 처리됩니다(즉, 현재 매크로 이름으로 정의된 각 식별자는 해당 전처리 토큰들의 대체 목록으로 교체됩니다).
모든 치환 후 생성된 지시문이 앞의 두 가지 형태 중 하나와 일치하지 않으면, 동작은 정의되지 않습니다.
< > 전처리 토큰 쌍 사이의 전처리 토큰 시퀀스 또는 " 문자 쌍이 단일 헤더 이름 전처리 토큰으로 결합되는 방식은 구현에 따라 정의됩니다.
4) h-char-sequence 또는 q-char-sequence 로 식별된 헤더 또는 소스 파일은 해당 전처리 토큰 시퀀스가 구문 (3) pp-tokens 인 것처럼 검색되며, 추가 매크로 확장은 수행되지 않습니다.
  • 이러한 지시문이 #include 지시문의 구문 요구사항을 충족하지 않는 경우 프로그램은 ill-formed입니다.
  • 그렇지 않으면, __has_include 표현식은 소스 파일 검색이 성공하면 1 로 평가되고, 검색이 실패하면 0 로 평가됩니다.
5) 이 형식은 구문 (4) 가 일치하지 않는 경우에만 고려되며, 이 경우 전처리 토큰은 일반 텍스트에서와 동일하게 처리됩니다.

header-name 으로 식별되는 헤더(즉, < h-char-sequence > 또는 " q-char-sequence " )가 import 가능한 헤더를 나타내는 경우, #include 전처리 지시문이 다음 형식의 import 지시문 으로 대체되는지는 구현에 따라 정의됩니다.

import header-name ; new-line

(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 소스 파일 포함