Binary resource inclusion (since C23)
#embed 는 빌드 시 (바이너리) 리소스를 포함하기 위한 전처리기 지시문으로, 여기서 리소스는 번역 환경에서 접근 가능한 데이터 소스로 정의됩니다.
목차 |
구문
#embed <
h-char-sequence
>
embed-parameter-sequence
(선택 사항)
new-line
|
(1) | ||||||||
#embed "
q-char-sequence
"
embed-parameter-sequence
(선택 사항)
new-line
|
(2) | ||||||||
#embed
pp-tokens
new-line
|
(3) | ||||||||
__has_embed
(
"
q-char-sequence
"
embed-parameter-sequence
(선택 사항)
)
__has_embed
(
<
h-char-sequence
>
embed-parameter-sequence
(선택 사항)
)
|
(4) | ||||||||
__has_embed
(
string-literal
pp-balanced-token-sequence
(선택 사항)
)
__has_embed
(
<
h-pp-tokens
>
pp-balanced-token-sequence
(선택 사항)
)
|
(5) | ||||||||
| new-line | - | 개행 문자 |
| h-char-sequence | - |
하나 이상의
h-char
시퀀스. 다음 중 어느 하나가 나타나면 정의되지 않은 동작을 유발함:
|
| h-char | - | 소스 문자 집합 의 구성원 중 개행 문자와 > 를 제외한 모든 문자 |
| q-char-sequence | - |
하나 이상의
q-char
시퀀스. 다음 중 어느 하나가 나타나면 정의되지 않은 동작을 유발함:
|
| q-char | - | 소스 문자 집합 의 구성원 중 개행 문자와 " 를 제외한 모든 문자 |
| pp-tokens | - | 하나 이상의 전처리 토큰 시퀀스 |
| string-literal | - | 문자열 리터럴 |
| h-pp-tokens | - | 전처리 토큰 중 > 를 제외한 하나 이상의 시퀀스 |
| embed-parameter-sequence | - | 하나 이상의 pp-parameter 시퀀스. attribute-list 와 달리 이 시퀀스는 쉼표로 구분되지 않음. |
| pp-parameter | - | attribute-token ( 속성 참조)이지만 토큰 대신 전처리 토큰으로 구성됨 |
| pp-balanced-token-sequence | - | balanced-token-sequence ( 속성 참조)이지만 토큰 대신 전처리 토큰으로 구성됨 |
설명
embed
이후의 전처리 토큰들은 일반 텍스트에서와 동일하게 처리됩니다(즉, 매크로 이름으로 현재 정의된 각 식별자는 해당 전처리 토큰들의 대체 목록으로 교체됩니다). 모든 대체 후 생성된 지시문은 앞의 두 가지 형식 중 하나와 일치해야 합니다.
<
와
>
전처리 토큰 쌍 사이의 전처리 토큰 시퀀스 또는 한 쌍의
"
문자 사이의 시퀀스가 단일 헤더 이름 전처리 토큰으로 결합되는 방법은 구현에 따라 정의됩니다.
리소스를 찾을 수 없거나 매개변수 중 하나가 구현에서 지원되지 않는 경우, 프로그램은 형식이 잘못되었습니다(ill-formed).
__has_embed 는 #if 및 #elif 표현식에서 확장될 수 있습니다. #ifdef , #ifndef , #elifdef , #elifndef 및 defined 에 의해 정의된 매크로로 취급되지만 다른 곳에서는 사용할 수 없습니다.
리소스는 구현에서 정의된 비트 단위의 크기인
구현 리소스 너비
를 가집니다. 리소스의
리소스 너비
는
limit
매개변수로 수정되지 않는 한 구현 리소스 너비입니다. 리소스 너비가 0이면 해당 리소스는 비어 있는 것으로 간주됩니다.
임베드 요소 너비
는 구현 정의 매개변수로 수정되지 않는 한
CHAR_BIT
와 동일합니다. 리소스 너비는 임베드 요소 너비로 나누어져야 합니다.
#embed
지시문의 확장은 아래에 설명된 정수
상수 표현식
목록으로부터 형성된 토큰 시퀀스입니다. 목록 내 각 정수 상수 표현식에 대한 토큰 그룹은 이전 정수 상수 표현식에 대한 토큰 그룹과 쉼표로 구분됩니다. 시퀀스는 쉼표로 시작하거나 끝나지 않습니다. 정수 상수 표현식 목록이 비어 있는 경우 토큰 시퀀스도 비어 있습니다. 지시문은 해당 확장으로 대체되며, 특정 embed 매개변수가 존재할 경우 추가 또는 대체 토큰 시퀀스가 함께 적용됩니다.
확장된 시퀀스 내 정수 상수 표현식들의 값은 리소스 데이터의 구현체 정의 매핑에 의해 결정됩니다. 각 정수 상수 표현식의 값은
[
0
,
2
embed element width
)
범위 내에 있습니다. 만약:
- 정수 상수 표현식의 목록은 unsigned char 와 호환되는 타입의 배열을 초기화하는 데 사용되거나, char 가 음수 값을 저장할 수 없는 경우 char 와 호환되는 타입의 배열을 초기화하는 데 사용되며,
- embed 요소의 너비는 CHAR_BIT 와 동일합니다.
그렇다면 배열의 초기화된 요소들의 내용은 번역 시점에 리소스의 바이너리 데이터가 배열로 fread 된 것과 같습니다.
구현체는 번역 시 비트 및 바이트 순서와 실행 시 비트 및 바이트 순서를 모두 고려하여 지시문의 리소스 바이너리 데이터를 더 적절하게 표현하도록 권장됩니다. 이는 번역 시 #embed 지시문을 통해 참조된 리소스가 실행 시 수단(예: fread 등)으로 접근된 동일한 리소스일 경우, 연속 저장소에 읽혀진 데이터가 #embed 지시문의 확장 내용으로 초기화된 문자 타입 배열과 비트 단위로 동일하게 비교될 가능성을 최대화합니다.
매개변수
표준은
limit
,
prefix
,
suffix
그리고
if_empty
매개변수를 정의합니다. 지시자에 나타나는 다른 모든 매개변수는 구현에서 정의되어야 하며, 그렇지 않으면 프로그램은 형식에 맞지 않습니다. 구현에서 정의된 임베드 매개변수는 지시자의 의미론을 변경할 수 있습니다.
limit
limit(
constant-expression
)
|
(1) | ||||||||
__limit__(
constant-expression
)
|
(2) | ||||||||
limit
임베드 매개변수는 임베드 매개변수 시퀀스에서 최대 한 번만 나타날 수 있습니다. 이 매개변수는 인수를 가져야 하며, 이 인수는 (전처리기)
상수 표현식
으로 평가되는 음수가 아닌 정수여야 하며
defined
토큰을 포함하지 않아야 합니다. 리소스 너비는 정수 상수 표현식에 임베드 요소 너비를 곱한 값과 구현 리소스 너비 중 더 작은 값으로 설정됩니다.
접미사
suffix(
pp-balanced-token-sequence
(선택 사항)
)
|
(1) | ||||||||
__suffix__(
pp-balanced-token-sequence
(선택 사항)
)
|
(2) | ||||||||
suffix
임베드 매개변수는 임베드 매개변수 시퀀스에서 최대 한 번만 나타날 수 있습니다. 이는 (비어 있을 수도 있는) 전처리기 인수 절을 가져야 합니다. 리소스가 비어 있지 않으면 매개변수 절의 내용이 지시문의 확장 바로 뒤에 배치됩니다. 그렇지 않으면 아무런 효과가 없습니다.
접두사
prefix(
pp-balanced-token-sequence
(선택 사항)
)
|
(1) | ||||||||
__prefix__(
pp-balanced-token-sequence
(선택 사항)
)
|
(2) | ||||||||
prefix
임베디드 매개변수는 임베디드 매개변수 시퀀스에서 최대 한 번만 나타날 수 있습니다. 이는 (비어 있을 수도 있는) 전처리기 인수 절을 가져야 합니다. 리소스가 비어 있지 않으면, 매개변수 절의 내용이 지시문의 확장 바로 앞에 배치됩니다. 그렇지 않으면 아무런 효과가 없습니다.
if_empty
if_empty(
pp-balanced-token-sequence
(선택적)
)
|
(1) | ||||||||
__if_empty__(
pp-balanced-token-sequence
(선택적)
)
|
(2) | ||||||||
if_empty
임베드 매개변수는 임베드 매개변수 시퀀스에서 최대 한 번만 나타날 수 있습니다. 이 매개변수는 (비어 있을 수도 있는) 전처리기 인자 절을 가져야 합니다. 리소스가 비어 있는 경우, 매개변수 절의 내용이 지시문을 대체합니다. 그렇지 않으면 아무런 효과가 없습니다.
예제
#include <stdint.h> #include <stdio.h> const uint8_t image_data[] = { #embed "image.png" }; const char message[] = { #embed "message.txt" if_empty('M', 'i', 's', 's', 'i', 'n', 'g', '\n') ,'\0' // null terminator }; void dump(const uint8_t arr[], size_t size) { for (size_t i = 0; i != size; ++i) printf("%02X%c", arr[i], (i + 1) % 16 ? ' ' : '\n'); puts(""); } int main() { puts("image_data[]:"); dump(image_data, sizeof image_data); puts("message[]:"); dump((const uint8_t*)message, sizeof message); }
가능한 출력:
image_data[]: 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 00 01 00 00 00 01 01 03 00 00 00 25 DB 56 ... message[]: 4D 69 73 73 69 6E 67 0A 00
참고문헌
- C23 표준 (ISO/IEC 9899:2024):
-
- 6.4.7 헤더 이름 (p: 69)
-
- 6.10.1 조건부 포함 (p: 165-169)
-
- 6.10.2 이진 리소스 포함 (p: 170-177)
참고 항목
|
C++ documentation
for
Resource inclusion
(since C++26)
|