Resource inclusion (since C++26)
#embed es una directiva de preprocesador para incluir recursos .
Contenidos |
Sintaxis
#embed <
secuencia-de-caracteres-h
>
tokens-pp
nueva-línea
|
(1) | ||||||||
#embed "
secuencia-de-caracteres-q
"
tokens-pp
nueva-línea
|
(2) | ||||||||
#embed
tokens-pp
nueva-línea
|
(3) | ||||||||
__has_embed
(
tokens-pp-equilibrados
)
|
(4) | ||||||||
| new-line | - | El carácter de nueva línea |
| h-char-sequence | - |
Una secuencia de uno o más
h-char
s (ver
#include
)
|
| q-char-sequence | - |
Una secuencia de uno o más
q-char
s (ver
#include
)
|
| pp-tokens | - | Una secuencia de uno o más preprocessing tokens |
| balanced-pp-tokens | - | Una secuencia de uno o más preprocessing tokens, donde todos los ( , [ y { están correctamente cerrados |
Explicación
embed
en la directiva se procesan igual que en el texto normal (es decir, cada identificador actualmente definido como nombre de macro se reemplaza por su lista de reemplazo de tokens de preprocesamiento).
- Si dicha directiva no cumple los requisitos sintácticos de una directiva #embed , el programa está mal formado.
-
En caso contrario, si la búsqueda del recurso tiene éxito y todos los
parámetros embed
dados en la directiva inventada son compatibles, la expresión
__has_embedse evalúa como __STDC_EMBED_FOUND__ si el recurso no está vacío, y como __STDC_EMBED_EMPTY__ si el recurso está vacío. -
En caso contrario, la expresión
__has_embedse evalúa como __STDC_EMBED_NOT_FOUND__ .
Recursos
Un recurso es una fuente de datos accesible desde el entorno de traducción. Un recurso tiene un implementation-resource-width , que es el tamaño en bits definido por la implementación del recurso. Si el implementation-resource-width no es un múltiplo entero de CHAR_BIT , el programa está mal formado.
Sea
implementation-resource-count
el resultado de implementation-resource-width dividido por
CHAR_BIT
. Cada recurso también tiene un
resource-count
, que es el implementation-resource-count, a menos que se proporcione el parámetro de incrustación
limit
.
Un recurso está vacío si el contador de recursos es cero.
// malformado si el ancho-de-recurso-de-implementación es de 6 bits #embed "6_bits.bin"
Incrustación de recursos
A menos que se modifique de otra manera, la directiva #embed es reemplazada por una lista separada por comas de literales enteros de tipo int .
Los literales enteros en la lista separada por comas corresponden a llamadas consecutivas de resource-count a std::fgetc desde el recurso, como un archivo binario. Si cualquier llamada a std::fgetc devuelve EOF , el programa está mal formado.
int i = { #embed "i.dat" }; // bien formado si i.dat produce un único valor int i2 = #embed "i.dat" ; // también bien formado si i.dat produce un único valor struct T { double a, b, c; struct { double e, f, g; } x; double h, i, j; }; T x = { // bien formado si la directiva produce nueve o menos valores #embed "s.dat" };
Parámetros de incrustación
Si pp-tokens está presente en la sintaxis (1) o en la sintaxis (2) , se procesa igual que en el texto normal. Los pp-tokens procesados deben formar una secuencia de parámetros de incrustación , de lo contrario el programa está mal formado. Los parámetros de incrustación tienen la siguiente sintaxis:
limit
(
balanced-pp-tokens
)
|
(1) | ||||||||
prefix
(
balanced-pp-tokens
(opcional)
)
|
(2) | ||||||||
suffix
(
balanced-pp-tokens
(opcional)
)
|
(3) | ||||||||
if_empty
(
balanced-pp-tokens
(opcional)
)
|
(4) | ||||||||
identifier
::
identifier
|
(5) | ||||||||
identifier
::
identifier
(
balanced-pp-tokens
(opcional)
)
|
(6) | ||||||||
limit
parámetro
Un parámetro de incrustación de la forma
limit
(
balanced-pp-tokens
)
puede aparecer como máximo una vez en cada directiva
#embed
.
balanced-pp-tokens
se procesan igual que en el texto normal para formar una
expresión constante
, pero las expresiones
defined
,
__has_include
,
__has_cpp_attribute
y
__has_embed
no se evalúan.
La expresión constante debe ser una integral constant expression cuyo valor sea mayor o igual a cero:
- Si el valor de la expresión constante es mayor que implementation-resource-count, el resource-count sigue siendo implementation-resource-count.
- De lo contrario, el resource-count se convierte en el valor de la expresión constante.
constexpr unsigned char sound_signature[] = { // un recurso hipotético capaz de expandirse a cuatro o más elementos #embed <sdk/jump.wav> limit(2 + 2) }; static_assert(sizeof(sound_signature) == 4); // equivalente a #embed <data.dat> limit(10) #define DATA_LIMIT 10 #embed <data.dat> limit(DATA_LIMIT) // mal formado #embed <data.dat> limit(__has_include("a.h"))
prefix
parámetro
Un parámetro de inserción de la forma
prefix
(
balanced-pp-tokens
(opcional)
)
puede aparecer como máximo una vez en cada
#embed
directiva.
Si el recurso está vacío, este parámetro de incrustación se ignora. De lo contrario, balanced-pp-tokens se coloca inmediatamente antes de la lista delimitada por comas de literales integrales.
suffix
parámetro
Un parámetro de embed de la forma
suffix
(
balanced-pp-tokens
(opcional)
)
puede aparecer como máximo una vez en cada directiva
#embed
.
Si el recurso está vacío, este parámetro de incrustación se ignora. De lo contrario, balanced-pp-tokens se coloca inmediatamente después de la lista delimitada por comas de literales integrales.
constexpr unsigned char whl[] = { #embed "chess.glsl" \ prefix(0xEF, 0xBB, 0xBF, ) /∗ una secuencia de bytes ∗/ \ suffix(,) 0 }; // siempre terminado en nulo, contiene la secuencia si no está vacío 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
parámetro
Un parámetro de incrustación de la forma
if_empty
(
balanced-pp-tokens
(opcional)
)
puede aparecer como máximo una vez en cada directiva
#embed
.
Si el recurso no está vacío, este parámetro de incrustación se ignora. De lo contrario, la directiva #embed se reemplaza por balanced-pp-tokens .
// siempre se expande a 42203 independientemente del contenido de /owo/uwurandom #embed </owo/uwurandom> if_empty(42203) limit(0)
Notas
| Macro de prueba de características | Valor | Std | Característica |
|---|---|---|---|
__cpp_pp_embed
|
202502L
|
(C++26) | La directiva #embed |
Ejemplo
Demuestre el efecto de
#embed
. Si
data.dat
puede ser incrustado como un recurso en el entorno de traducción, ninguna aserción en este programa debería fallar.
#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); // mismo archivo en entorno de ejecución que fue incrustado 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); }
Referencias
- Estándar C++26 (ISO/IEC 14882:2026):
-
- 15.4 Inclusión de recursos [cpp.embed]
Véase también
|
Documentación de C
para
Inclusión de recursos binarios
(desde C23)
|