Resource inclusion (since C++26)
#embed ist eine Präprozessor-Direktive zum Einbinden von Ressourcen .
Inhaltsverzeichnis |
Syntax
#embed <
h-Zeichenfolge
>
Präprozessor-Tokens
Zeilenumbruch
|
(1) | ||||||||
#embed "
q-Zeichenfolge
"
Präprozessor-Tokens
Zeilenumbruch
|
(2) | ||||||||
#embed
Präprozessor-Tokens
Zeilenumbruch
|
(3) | ||||||||
__has_embed
(
ausgeglichene-Präprozessor-Tokens
)
|
(4) | ||||||||
| new-line | - | Das Zeilenumbruchzeichen |
| h-char-sequence | - |
Eine Sequenz von einem oder mehreren
h-char
s (siehe
#include
)
|
| q-char-sequence | - |
Eine Sequenz von einem oder mehreren
q-char
s (siehe
#include
)
|
| pp-tokens | - | Eine Sequenz von einem oder mehreren Präprozessor-Tokens |
| balanced-pp-tokens | - | Eine Sequenz von einem oder mehreren Präprozessor-Tokens, bei der alle ( , [ und { korrekt geschlossen sind |
Erklärung
embed
in der Direktive werden genauso verarbeitet wie in normalem Text (d.h., jeder Bezeichner, der aktuell als Makroname definiert ist, wird durch seine Ersetzungsliste von Präprozessor-Token ersetzt).
- Wenn eine solche Direktive die syntaktischen Anforderungen einer #embed -Direktive nicht erfüllen würde, ist das Programm fehlerhaft.
-
Andernfalls, wenn die Suche nach der Ressource erfolgreich ist und alle angegebenen
Embed-Parameter
in der erfundenen Direktive unterstützt werden, wertet der
__has_embed-Ausdruck zu __STDC_EMBED_FOUND__ aus, wenn die Ressource nicht leer ist, und zu __STDC_EMBED_EMPTY__ , wenn die Ressource leer ist. -
Andernfalls wertet der
__has_embed-Ausdruck zu __STDC_EMBED_NOT_FOUND__ aus.
Ressourcen
Eine Resource ist eine Datenquelle, die aus der Übersetzungsumgebung zugänglich ist. Eine Resource hat eine Implementierungs-Resource-Breite , welche die implementierungsdefinierte Größe der Resource in Bits ist. Wenn die Implementierungs-Resource-Breite kein ganzzahliges Vielfaches von CHAR_BIT ist, ist das Programm fehlerhaft.
Sei
implementation-resource-count
gleich implementation-resource-width geteilt durch
CHAR_BIT
. Jede Ressource hat außerdem einen
resource-count
, welcher dem implementation-resource-count entspricht, es sei denn, der
limit
-Embed-Parameter wird angegeben.
Eine Ressource ist empty , wenn die Ressourcenanzahl null ist.
// ill-formed if the implementation-resource-width is 6 bits #embed "6_bits.bin"
Einbettung von Ressourcen
Sofern nicht anders modifiziert, wird die #embed -Direktive ersetzt durch eine kommagetrennte Liste von Integer-Literalen vom Typ int .
Die ganzzahligen Literale in der durch Kommas getrennten Liste entsprechen aufeinanderfolgenden Aufrufen von std::fgetc aus der Ressource, als Binärdatei. Wenn irgendein Aufruf von std::fgetc den Wert EOF zurückgibt, ist das Programm fehlerhaft.
int i = { #embed "i.dat" }; // wohlgeformt, wenn i.dat einen einzelnen Wert erzeugt int i2 = #embed "i.dat" ; // ebenfalls wohlgeformt, wenn i.dat einen einzelnen Wert erzeugt struct T { double a, b, c; struct { double e, f, g; } x; double h, i, j; }; T x = { // wohlgeformt, wenn die Direktive neun oder weniger Werte erzeugt #embed "s.dat" };
Einbettungsparameter
Wenn pp-tokens in Syntax (1) oder Syntax (2) vorhanden ist, wird es genau wie in normalem Text verarbeitet. Die verarbeiteten pp-tokens sollten eine Sequenz von Embed-Parametern bilden, andernfalls ist das Programm fehlerhaft. Embed-Parameter haben folgende Syntax:
limit
(
balanced-pp-tokens
)
|
(1) | ||||||||
prefix
(
balanced-pp-tokens
(optional)
)
|
(2) | ||||||||
suffix
(
balanced-pp-tokens
(optional)
)
|
(3) | ||||||||
if_empty
(
balanced-pp-tokens
(optional)
)
|
(4) | ||||||||
identifier
::
identifier
|
(5) | ||||||||
identifier
::
identifier
(
balanced-pp-tokens
(optional)
)
|
(6) | ||||||||
limit
Parameter
Ein Einbettungsparameter der Form
limit
(
balanced-pp-tokens
)
darf höchstens einmal in jeder
#embed
Direktive erscheinen.
balanced-pp-tokens
werden genauso wie normaler Text verarbeitet, um einen
constant expression
zu bilden, aber
defined
,
__has_include
,
__has_cpp_attribute
und
__has_embed
Ausdrücke werden nicht ausgewertet.
Der konstante Ausdruck muss ein integral constant expression sein, dessen Wert größer oder gleich null ist:
- Wenn der Wert des konstanten Ausdrucks größer als die Implementierungsressourcenanzahl ist, bleibt die Ressourcenanzahl die Implementierungsressourcenanzahl.
- Andernfalls wird die Ressourcenanzahl der Wert des konstanten Ausdrucks.
constexpr unsigned char sound_signature[] = { // eine hypothetische Ressource, die sich auf vier oder mehr Elemente erweitern kann #embed <sdk/jump.wav> limit(2 + 2) }; static_assert(sizeof(sound_signature) == 4); // äquivalent zu #embed <data.dat> limit(10) #define DATA_LIMIT 10 #embed <data.dat> limit(DATA_LIMIT) // fehlerhaft #embed <data.dat> limit(__has_include("a.h"))
prefix
Parameter
Ein Einbettungsparameter der Form
prefix
(
balanced-pp-tokens
(optional)
)
darf höchstens einmal in jeder
#embed
-Direktive vorkommen.
Wenn die Ressource leer ist, wird dieser Einbettungsparameter ignoriert. Andernfalls wird balanced-pp-tokens unmittelbar vor die durch Kommas getrennte Liste von ganzzahligen Literalen platziert.
suffix
-Parameter
Ein Einbettungsparameter der Form
suffix
(
balanced-pp-tokens
(optional)
)
darf höchstens einmal in jeder
#embed
Direktive erscheinen.
Wenn die Ressource leer ist, wird dieser Einbettungsparameter ignoriert. Andernfalls wird balanced-pp-tokens unmittelbar nach der durch Kommas getrennten Liste von Integral-Literalen platziert.
constexpr unsigned char whl[] = { #embed "chess.glsl" \ prefix(0xEF, 0xBB, 0xBF, ) /∗ eine Bytefolge ∗/ \ suffix(,) 0 }; // immer nullterminiert, enthält die Sequenz falls nicht leer 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
Parameter
Ein Einbettungsparameter der Form
if_empty
(
balanced-pp-tokens
(optional)
)
darf höchstens einmal in jeder
#embed
-Direktive vorkommen.
Wenn die Ressource nicht leer ist, wird dieser Einbettungsparameter ignoriert. Andernfalls wird die #embed -Direktive ersetzt durch balanced-pp-tokens .
// erweitert sich immer auf 42203, unabhängig vom Inhalt von /owo/uwurandom #embed </owo/uwurandom> if_empty(42203) limit(0)
Hinweise
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_pp_embed
|
202502L
|
(C++26) | Die #embed Direktive |
Beispiel
Demonstrieren Sie die Wirkung von
#embed
. Wenn
data.dat
als Ressource in der Übersetzungsumgebung eingebettet werden kann, sollte keine Assertion in diesem Programm fehlschlagen.
#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); // dieselbe Datei in der Ausführungsumgebung wie eingebettet 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); }
Referenzen
- C++26-Standard (ISO/IEC 14882:2026):
-
- 15.4 Ressourcen-Einbindung [cpp.embed]
Siehe auch
|
C-Dokumentation
für
Binäre Ressourcen-Einbindung
(seit C23)
|