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 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)
1) Busca un recurso identificado de forma única por h-char-sequence y reemplaza la directiva por el contenido completo del recurso.
2) Busca un recurso identificado por q-char-sequence y reemplaza la directiva por el contenido completo del archivo fuente. Puede recurrir a (1) y tratar q-char-sequence como un identificador de recurso.
3) Si ni (1) ni (2) coinciden, los pp-tokens sufrirán reemplazo de macro. La directiva después del reemplazo se intentará hacer coincidir con (1) o (2) nuevamente.
4) Verifica si un recurso está disponible para inclusión con los parámetros de incrustación dados .
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

1) Busca una secuencia de lugares para un recurso identificado de forma única por h-char-sequence , y provoca el reemplazo de esa directiva por el contenido completo del encabezado. La forma en que se especifican los lugares o se identifica el encabezado está definida por la implementación.
2) Provoca el reemplazo de esa directiva por el contenido completo del recurso identificado por q-char-sequence . El recurso nombrado se busca de una manera definida por la implementación.
Si esta búsqueda no es compatible, o si la búsqueda falla, la directiva se reprocesa como si leyera sintaxis (1) con la secuencia contenida idéntica (incluyendo > caracteres, si los hay) de la directiva original.
3) Los tokens de preprocesamiento después de 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 la directiva resultante después de todas las sustituciones no coincide con una de las dos formas anteriores, el comportamiento es indefinido.
El método mediante el cual una secuencia de tokens de preprocesamiento entre un < y un > par de tokens de preprocesamiento o un par de caracteres " se combina en un único token de preprocesamiento de nombre de recurso está definido por la implementación.
4) Busca un recurso identificado por una directiva #embed inventada de sintaxis (3) , utilizando balanced-pp-tokens como sus pp-tokens .
  • 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_embed se 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_embed se 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)
1-4) Parámetros de incrustación estándar.
1) Limita el recuento de recursos del recurso que se va a incrustar.
2) Agrega prefijo al recurso no vacío incrustado.
3) Agrega sufijo al recurso no vacío incrustado.
4) Reemplaza el recurso incrustado si está vacío.
5,6) Parámetros de incrustación no estándar. Cualquier parámetro de este tipo es condicionalmente compatible, con semántica definida por la implementación.

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)