Resource inclusion (since C++26)
#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) | ||||||||
`, `
`, `
| new-line | - | 개행 문자 |
| h-char-sequence | - |
하나 이상의
h-char
시퀀스 (
#include
참조)
|
| q-char-sequence | - |
하나 이상의
q-char
시퀀스 (
#include
참조)
|
| pp-tokens | - | 하나 이상의 전처리 토큰 시퀀스 |
| balanced-pp-tokens | - | 하나 이상의 전처리 토큰 시퀀스로, 모든 ( , [ 및 { 가 적절히 닫힌 상태 |
설명
embed
이후의 전처리 토큰들은 일반 텍스트에서와 동일하게 처리됩니다(즉, 현재 매크로 이름으로 정의된 각 식별자는 해당 전처리 토큰들의 대체 목록으로 교체됩니다).
- 해당 지시문이 #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) | ||||||||
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)
|