Namespaces
Variants

Resource inclusion (since C++26)

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

#embed 리소스 를 포함하기 위한 전처리기 지시문입니다.

목차

구문

#embed < h-char-sequence > pp-tokens new-line (1)
#embed " q-char-sequence " pp-tokens new-line (2)
#embed pp-tokens new-line (3)
__has_embed ( balanced-pp-tokens ) (4)
**참고**: 이 번역에서는 C++ 전처리기 지시어와 관련된 용어들은 원문 그대로 유지되었으며, HTML 태그와 속성, 그리고 ` `, `
`, `` 태그 내의 내용은 번역되지 않았습니다.
1) h-char-sequence 로 고유하게 식별되는 리소스를 검색하고 해당 지시문을 리소스의 전체 내용으로 대체합니다.
2) q-char-sequence 로 식별된 리소스를 검색하고 해당 지시문을 소스 파일 전체 내용으로 대체합니다. (1) 로 폴백하여 q-char-sequence 를 리소스 식별자로 처리할 수 있습니다.
3) 만약 (1) (2) 도 매칭되지 않으면, pp-tokens 는 매크로 치환을 거칩니다. 치환 후의 지시문은 (1) 또는 (2) 와 다시 매칭을 시도합니다.
4) 주어진 embed parameters 로 리소스 포함이 가능한지 확인합니다.
new-line - 개행 문자
h-char-sequence - 하나 이상의 h-char  시퀀스 ( #include 참조)
q-char-sequence - 하나 이상의 q-char  시퀀스 ( #include 참조)
pp-tokens - 하나 이상의 전처리 토큰 시퀀스
balanced-pp-tokens - 하나 이상의 전처리 토큰 시퀀스로, 모든 ( , [ { 가 적절히 닫힌 상태

설명

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

리소스

리소스 는 번역 환경에서 접근 가능한 데이터의 원천입니다. 리소스는 구현-리소스-너비 를 가지며, 이는 구현에서 정의된 리소스의 비트 단위 크기입니다. 구현-리소스-너비가 CHAR_BIT 의 정수 배수가 아닌 경우, 프로그램은 형식에 맞지 않습니다.

implementation-resource-count 를 implementation-resource-width를 CHAR_BIT 로 나눈 값으로 설정합니다. 모든 리소스는 또한 resource-count  를 가지며, 이는 limit embed 매개변수가 제공되지 않는 한 implementation-resource-count입니다.

리소스는 리소스 카운트가 0인 경우 비어 있음 으로 간주됩니다.

// 구현체의 리소스 너비가 6비트인 경우 형식 오류
#embed "6_bits.bin"

리소스 임베딩

달리 수정되지 않는 한, #embed 지시문은 정수 리터럴 의 쉼표로 구분된 목록으로 대체되며, 이 리터럴들의 타입은 int 입니다.

쉼표로 구분된 목록의 정수 리터럴들은 리소스에 대한 resource-count 회의 연속적인 std::fgetc 호출에 해당하며, 바이너리 파일로 처리됩니다. 만약 std::fgetc 호출 중 어떤 것이 EOF 를 반환하면, 프로그램은 ill-formed입니다.

int i =
{
#embed "i.dat"
}; // i.dat가 단일 값을 생성할 경우 올바른 형식
int i2 =
#embed "i.dat"
; // i.dat가 단일 값을 생성할 경우 역시 올바른 형식
struct T
{
    double a, b, c;
    struct { double e, f, g; } x;
    double h, i, j;
};
T x =
{
// 지시문이 9개 이하의 값을 생성할 경우 올바른 형식
#embed "s.dat"
};

임베드 매개변수

만약 pp-tokens 가 구문 (1) 또는 구문 (2) 에 존재한다면, 일반 텍스트에서와 동일하게 처리됩니다. 처리된 pp-tokens 는 일련의 embed parameters  를 형성해야 하며, 그렇지 않으면 프로그램은 ill-formed입니다. Embed parameters는 다음 구문을 가집니다:

limit ( balanced-pp-tokens ) (1)
prefix ( balanced-pp-tokens  (선택적) ) (2)
suffix ( balanced-pp-tokens  (선택적) ) (3)
if_empty ( balanced-pp-tokens  (선택적) ) (4)
identifier :: identifier (5)
identifier :: identifier ( balanced-pp-tokens  (선택적) ) (6)
1-4) 표준 임베드 매개변수.
1) 포함될 리소스의 리소스 카운트를 제한합니다.
2) 내장된 비어 있지 않은 리소스에 접두사를 추가합니다.
3) 내장된 비어 있지 않은 리소스에 접미사를 추가합니다.
4) 임베디드 리소스가 비어 있을 경우 이를 교체합니다.
5,6) 비표준 임베디드 매개변수. 이러한 모든 매개변수는 조건부 지원되며, 구현에서 정의하는 의미 체계를 가집니다.

limit 매개변수

limit ( balanced-pp-tokens ) 형식의 embed 매개변수는 각 #embed 지시문에서 최대 한 번만 나타날 수 있습니다.

balanced-pp-tokens 는 일반 텍스트에서와 동일하게 처리되어 constant expression 을 형성하지만, defined , __has_include , __has_cpp_attribute __has_embed 표현식은 평가되지 않습니다.

상수 표현식은 값이 0보다 크거나 같은 integral constant expression 이어야 합니다:

  • 상수 표현식의 값이 구현-리소스-개수보다 큰 경우, 리소스-개수는 여전히 구현-리소스-개수입니다.
  • 그렇지 않은 경우, 리소스-개수는 상수 표현식의 값이 됩니다.
constexpr unsigned char sound_signature[] =
{
// 4개 이상의 요소로 확장 가능한 가상의 리소스
#embed <sdk/jump.wav> limit(2 + 2)
};
static_assert(sizeof(sound_signature) == 4);
// #embed <data.dat> limit(10)와 동등함
#define DATA_LIMIT 10
#embed <data.dat> limit(DATA_LIMIT)
// 잘못된 형식
#embed <data.dat> limit(__has_include("a.h"))

prefix 매개변수

prefix ( balanced-pp-tokens  (선택 사항) ) 형식의 임베드 매개변수는 각 #embed 지시문에서 최대 한 번만 나타날 수 있습니다.

리소스가 비어 있는 경우, 이 임베드 매개변수는 무시됩니다. 그렇지 않으면, balanced-pp-tokens 가 쉼표로 구분된 정수 리터럴 목록 바로 앞에 배치됩니다.

suffix 매개변수

suffix 형태의 임베드 매개변수 ( balanced-pp-tokens  (선택적) ) 는 각 #embed 지시어에서 최대 한 번만 나타날 수 있습니다.

리소스가 비어 있는 경우, 이 임베드 매개변수는 무시됩니다. 그렇지 않으면, balanced-pp-tokens 가 쉼표로 구분된 정수 리터럴 목록 바로 뒤에 배치됩니다.

constexpr unsigned char whl[] =
{
#embed "chess.glsl" \
    prefix(0xEF, 0xBB, 0xBF, ) /∗ 바이트 시퀀스 ∗/ \
    suffix(,)
    0
};
// 항상 null로 종료되며, 비어 있지 않으면 시퀀스를 포함함
constexpr bool is_empty = sizeof(whl) == 1 && whl[0] == '\0';
constexpr bool is_not_empty = sizeof(whl) >= 4
    && whl[sizeof(whl) - 1] == '\0'
    && whl[0] == '\xEF' && whl[1] == '\xBB' && whl[2] == '\xBF';
static_assert(is_empty || is_not_empty);

if_empty 매개변수

if_empty 형식의 임베드 매개변수는 ( balanced-pp-tokens  (optional) ) 형태로 각 #embed 지시자에서 최대 한 번만 나타날 수 있습니다.

리소스가 비어 있지 않은 경우 이 임베드 매개변수는 무시됩니다. 그렇지 않으면 #embed 지시문이 balanced-pp-tokens 로 대체됩니다.

// /owo/uwurandom의 내용과 관계없이 항상 42203으로 확장됨
#embed </owo/uwurandom> if_empty(42203) limit(0)

참고 사항

기능 테스트 매크로 표준 기능
__cpp_pp_embed 202502L (C++26) #embed 지시문

예제

#embed 의 효과를 보여줍니다. data.dat 파일이 번역 환경에서 리소스로 포함될 수 있다면, 이 프로그램의 어떤 assert도 실패하지 않아야 합니다.

#include <cassert>
#include <cstddef>
#include <cstring>
#include <fstream>
#include <vector>
int main()
{
    constexpr unsigned char d[]
    {
#embed <data.dat>
    };
    const std::vector<unsigned char> vec_d
    {
#embed <data.dat>
    };
    constexpr std::size_t expected_size = sizeof(d);
    // 임베드된 것과 동일한 실행 환경의 파일
    std::ifstream f_source("data.dat", std::ios_base::binary | std::ios_base::in);
    unsigned char runtime_d[expected_size];
    char* ifstream_ptr = reinterpret_cast<char*>(runtime_d);
    assert(!f_source.read(ifstream_ptr, expected_size));
    std::size_t ifstream_size = f_source.gcount();
    assert(ifstream_size == expected_size);
    int is_same = std::memcmp(&d[0], ifstream_ptr, ifstream_size);
    assert(is_same == 0);
    int is_same_vec = std::memcmp(vec_d.data(), ifstream_ptr, ifstream_size);
    assert(is_same_vec == 0);
}

참고문헌

  • C++26 표준 (ISO/IEC 14882:2026):
  • 15.4 리소스 포함 [cpp.embed]

참고 항목

C 문서 for 이진 리소스 포함 (since C23)