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 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)
1) Sucht nach einer Ressource, die eindeutig durch h-char-sequence identifiziert wird, und ersetzt die Direktive durch den gesamten Inhalt der Ressource.
2) Such nach einer Ressource, identifiziert durch q-char-sequence , und ersetzt die Direktive durch den gesamten Inhalt der Quelldatei. Es kann auf (1) zurückgreifen und q-char-sequence als Ressourcenkennung behandeln.
3) Wenn weder (1) noch (2) zutrifft, werden pp-tokens einer Makroersetzung unterzogen. Die Anweisung wird nach der Ersetzung erneut versucht, mit (1) oder (2) abgeglichen zu werden.
4) Prüft, ob eine Ressource für die Einbindung mit den angegebenen Embed-Parametern verfügbar ist.
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

1) Durchsucht eine Folge von Orten nach einer Ressource, die eindeutig durch h-char-sequence  identifiziert wird, und bewirkt den Ersatz dieser Direktive durch den gesamten Inhalt des Headers. Wie die Orte spezifiziert oder der Header identifiziert wird, ist implementierungsdefiniert.
2) Bewirkt den Ersatz dieser Direktive durch den gesamten Inhalt der durch q-char-sequence  identifizierten Ressource. Die benannte Ressource wird auf implementationsabhängige Weise gesucht.
Wenn diese Suche nicht unterstützt wird oder fehlschlägt, wird die Direktive erneut verarbeitet, als ob sie die Syntax (1) mit der identischen enthaltenen Sequenz (einschließlich > Zeichen, falls vorhanden) aus der ursprünglichen Direktive enthält.
3) Die Präprozessor-Token nach 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 die Direktive nach allen Ersetzungen nicht einer der beiden vorherigen Formen entspricht, ist das Verhalten undefiniert.
Die Methode, durch die eine Sequenz von Präprozessor-Tokens zwischen einem < und einem > Präprozessor-Token-Paar oder einem Paar von " Zeichen zu einem einzelnen Ressourcennamen-Präprozessor-Token kombiniert wird, ist implementierungsdefiniert.
4) Sucht nach einer Ressource, die durch eine erfundene #embed -Direktive der Syntax (3) identifiziert wird, wobei balanced-pp-tokens als pp-tokens verwendet werden.
  • 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)
1-4) Standardeinbettungsparameter.
1) Begrenzt die Ressourcenanzahl der einzubettenden Ressource.
2) Fügt dem eingebetteten nicht-leeren Ressourcen ein Präfix hinzu.
3) Fügt dem eingebetteten nicht-leeren Ressourcen ein Suffix hinzu.
4) Ersetzt die eingebettete Ressource, wenn sie leer ist.
5,6) Nicht standardmäßige Einbettungsparameter. Jeder solche Parameter ist bedingt unterstützt, mit implementierungsdefinierter Semantik.

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)