Resource inclusion (since C++26)
#embed est une directive de préprocesseur pour inclure des ressources .
Table des matières |
Syntaxe
#embed <
séquence-caractères-h
>
jetons-pp
nouvelle-ligne
|
(1) | ||||||||
#embed "
séquence-caractères-q
"
jetons-pp
nouvelle-ligne
|
(2) | ||||||||
#embed
jetons-pp
nouvelle-ligne
|
(3) | ||||||||
__has_embed
(
jetons-pp-équilibrés
)
|
(4) | ||||||||
| new-line | - | Le caractère de nouvelle ligne |
| h-char-sequence | - |
Une séquence d'un ou plusieurs
h-char
s (voir
#include
)
|
| q-char-sequence | - |
Une séquence d'un ou plusieurs
q-char
s (voir
#include
)
|
| pp-tokens | - | Une séquence d'un ou plusieurs jetons de préprocesseur |
| balanced-pp-tokens | - | Une séquence d'un ou plusieurs jetons de préprocesseur, où tous les ( , [ et { sont correctement fermés |
Explication
embed
dans la directive sont traités comme dans le texte normal (c'est-à-dire que chaque identifiant actuellement défini comme nom de macro est remplacé par sa liste de remplacement de jetons de pré-traitement).
- Si une telle directive ne satisfait pas aux exigences syntaxiques d'une directive #embed , le programme est mal formé.
-
Sinon, si la recherche de la ressource réussit et que tous les
paramètres embed
donnés dans la directive inventée sont pris en charge, l'expression
__has_embedprend la valeur __STDC_EMBED_FOUND__ si la ressource n'est pas vide, et __STDC_EMBED_EMPTY__ si la ressource est vide. -
Sinon, l'expression
__has_embedprend la valeur __STDC_EMBED_NOT_FOUND__ .
Ressources
Une ressource est une source de données accessible depuis l'environnement de traduction. Une ressource possède une implementation-resource-width , qui est la taille en bits définie par l'implémentation de la ressource. Si l'implementation-resource-width n'est pas un multiple entier de CHAR_BIT , le programme est mal formé.
Soit
implementation-resource-count
la valeur implementation-resource-width divisée par
CHAR_BIT
. Chaque ressource possède également un
resource-count
, qui correspond à implementation-resource-count, sauf si le paramètre d'intégration
limit
est fourni.
Une ressource est vide si le compteur de ressources est zéro.
// malformé si la largeur de ressource d'implémentation est de 6 bits #embed "6_bits.bin"
Intégration des ressources
Sauf modification contraire, la directive #embed est remplacée par une liste délimitée par des virgules de littéraux entiers de type int .
Les littéraux entiers dans la liste délimitée par des virgules correspondent à des appels consécutifs de nombre-ressource à std::fgetc depuis la ressource, en tant que fichier binaire. Si un appel à std::fgetc retourne EOF , le programme est mal formé.
int i = { #embed "i.dat" }; // bien formé si i.dat produit une seule valeur int i2 = #embed "i.dat" ; // également bien formé si i.dat produit une seule valeur struct T { double a, b, c; struct { double e, f, g; } x; double h, i, j; }; T x = { // bien formé si la directive produit neuf valeurs ou moins #embed "s.dat" };
Paramètres d'intégration
Si pp-tokens est présent dans la syntaxe (1) ou la syntaxe (2) , il est traité comme dans un texte normal. Les pp-tokens traités doivent former une séquence de paramètres d'incorporation , sinon le programme est mal formé. Les paramètres d'incorporation ont la syntaxe suivante :
limit
(
jetons-pp-équilibrés
)
|
(1) | ||||||||
prefix
(
jetons-pp-équilibrés
(optionnel)
)
|
(2) | ||||||||
suffix
(
jetons-pp-équilibrés
(optionnel)
)
|
(3) | ||||||||
if_empty
(
jetons-pp-équilibrés
(optionnel)
)
|
(4) | ||||||||
identifiant
::
identifiant
|
(5) | ||||||||
identifiant
::
identifiant
(
jetons-pp-équilibrés
(optionnel)
)
|
(6) | ||||||||
limit
paramètre
Un paramètre d'intégration de la forme
limit
(
balanced-pp-tokens
)
ne peut apparaître qu'au maximum une fois dans chaque directive
#embed
.
balanced-pp-tokens
sont traités comme dans un texte normal pour former une
expression constante
, mais les expressions
defined
,
__has_include
,
__has_cpp_attribute
et
__has_embed
ne sont pas évaluées.
L'expression constante doit être une expression constante entière dont la valeur est supérieure ou égale à zéro :
- Si la valeur de l'expression constante est supérieure à implementation-resource-count, le resource-count reste l'implementation-resource-count.
- Sinon, le resource-count devient la valeur de l'expression constante.
constexpr unsigned char sound_signature[] = { // une ressource hypothétique capable de s'étendre à quatre éléments ou plus #embed <sdk/jump.wav> limit(2 + 2) }; static_assert(sizeof(sound_signature) == 4); // équivalent à #embed <data.dat> limit(10) #define DATA_LIMIT 10 #embed <data.dat> limit(DATA_LIMIT) // mal formé #embed <data.dat> limit(__has_include("a.h"))
prefix
paramètre
Un paramètre d'intégration de la forme
prefix
(
balanced-pp-tokens
(optionnel)
)
ne peut apparaître qu'au maximum une fois dans chaque directive
#embed
.
Si la ressource est vide, ce paramètre d'incorporation est ignoré. Sinon, balanced-pp-tokens est placé immédiatement avant la liste délimitée par des virgules de littéraux entiers.
suffix
paramètre
Un paramètre d'incorporation de la forme
suffix
(
balanced-pp-tokens
(optionnel)
)
ne peut apparaître qu'au plus une fois dans chaque directive
#embed
.
Si la ressource est vide, ce paramètre d'incorporation est ignoré. Sinon, balanced-pp-tokens est placé immédiatement après la liste délimitée par des virgules de littéraux entiers.
constexpr unsigned char whl[] = { #embed "chess.glsl" \ prefix(0xEF, 0xBB, 0xBF, ) /∗ une séquence d'octets ∗/ \ suffix(,) 0 }; // toujours terminé par null, contient la séquence si non vide 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
paramètre
Un paramètre d'incorporation de la forme
if_empty
(
balanced-pp-tokens
(optionnel)
)
ne peut apparaître qu'au maximum une fois dans chaque directive
#embed
.
Si la ressource n'est pas vide, ce paramètre d'incorporation est ignoré. Sinon, la directive #embed est remplacée par balanced-pp-tokens .
// s'étend toujours à 42203 indépendamment du contenu de /owo/uwurandom #embed </owo/uwurandom> if_empty(42203) limit(0)
Notes
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_pp_embed
|
202502L
|
(C++26) | La directive #embed |
Exemple
Démontrez l'effet de
#embed
. Si
data.dat
peut être intégré comme ressource dans l'environnement de traduction, aucune assertion dans ce programme ne devrait échouer.
#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); // même fichier dans l'environnement d'exécution que celui intégré 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); }
Références
- Norme C++26 (ISO/CEI 14882:2026) :
-
- 15.4 Inclusion de ressources [cpp.embed]
Voir aussi
|
Documentation C
pour
Inclusion de ressources binaires
(depuis C23)
|