[cpp.embed.gen] # 15 Preprocessing directives [[cpp]](./#cpp) ## 15.4 Resource inclusion [[cpp.embed]](cpp.embed#gen) ### 15.4.1 General [cpp.embed.gen] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L845) A [*bracket resource search*](#def:search,bracket_resource "15.4.1 General [cpp.embed.gen]") for a sequence of characters searches a sequence of places for a resource identified uniquely by that sequence of characters[.](#1.sentence-1) How the places are determined or the resource identified is implementation-defined[.](#1.sentence-2) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L852) A [*quote resource search*](#def:search,quote_resource "15.4.1 General [cpp.embed.gen]") for a sequence of characters attempts to identify a resource that is named by the sequence of characters[.](#2.sentence-1) The named resource is searched for in an implementation-defined manner[.](#2.sentence-2) If the implementation does not support a quote resource search for that sequence of characters, or if the search fails, the result of the quote resource search is the result of a bracket resource search for the same sequence of characters[.](#2.sentence-3) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L862) A preprocessing directive of the form # embed [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]") [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1 Preamble [cpp.pre]")opt [*new-line*](cpp.pre#nt:new-line "15.1 Preamble [cpp.pre]") causes the replacement of that directive by preprocessing tokens derived from data in the resource identified by [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]"), as specified below[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L872) If the [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]") is of the form < [*h-char-sequence*](lex.header#nt:h-char-sequence "5.6 Header names [lex.header]") > the resource is identified by a bracket resource search for the sequence of characters of the [*h-char-sequence*](lex.header#nt:h-char-sequence "5.6 Header names [lex.header]")[.](#4.sentence-1) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L880) If the [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]") is of the form " [*q-char-sequence*](lex.header#nt:q-char-sequence "5.6 Header names [lex.header]") " the resource is identified by a quote resource search for the sequence of characters of the [*q-char-sequence*](lex.header#nt:q-char-sequence "5.6 Header names [lex.header]")[.](#5.sentence-1) [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L888) If a bracket resource search fails, or if a quote or bracket resource search identifies a resource that cannot be processed by the implementation, the program is ill-formed[.](#6.sentence-1) [*Note [1](#note-1)*: If the resource cannot be processed, the program is ill-formed even when processing #embed with limit(0) ([[cpp.embed.param.limit]](cpp.embed.param.limit "15.4.2.1 limit parameter")) or evaluating __has_embed[.](#6.sentence-2) — *end note*] [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L898) *Recommended practice*: A mechanism similar to, but distinct from, theimplementation-defined search paths used for #include ([[cpp.include]](cpp.include "15.3 Source file inclusion")) is encouraged[.](#7.sentence-1) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L904) Either form of the #embed directive processes the[*pp-tokens*](cpp.pre#nt:pp-tokens "15.1 Preamble [cpp.pre]"), if present, just as in normal text[.](#8.sentence-1) The [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1 Preamble [cpp.pre]") shall then have the form[*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1 Preamble [cpp.pre]")[.](#8.sentence-2) [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L910) A resource is a source of data accessible from the translation environment[.](#9.sentence-1) A resource has an [*implementation-resource-width*](#def:implementation-resource-width "15.4.1 General [cpp.embed.gen]"), which is theimplementation-defined size in bits of the resource[.](#9.sentence-2) If the implementation-resource-width is not an integral multiple ofCHAR_BIT, the program is ill-formed[.](#9.sentence-3) Let [*implementation-resource-count*](#def:implementation-resource-count "15.4.1 General [cpp.embed.gen]") be implementation-resource-width divided by CHAR_BIT[.](#9.sentence-4) Every resource also has a [*resource-count*](#def:resource-count "15.4.1 General [cpp.embed.gen]"), which is - [(9.1)](#9.1) the value as computed from the optionally-provided limit[*embed-parameter*](cpp.pre#nt:embed-parameter "15.1 Preamble [cpp.pre]") ([[cpp.embed.param.limit]](cpp.embed.param.limit "15.4.2.1 limit parameter")), if present; - [(9.2)](#9.2) otherwise, the implementation-resource-count. A resource is empty if the resource-count is zero[.](#9.sentence-6) [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L931) [*Example [1](#example-1)*: // ill-formed if the implementation-resource-width is 6 bits#embed "6_bits.bin" — *end example*] [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L939) The #embed directive is replaced by a comma-separated list of integer literals of type int, unless otherwise modified by embed parameters ([[cpp.embed.param]](cpp.embed.param "15.4.2 Embed parameters"))[.](#11.sentence-1) [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L944) The integer literals in the comma-separated list correspond to resource-count consecutive calls to std​::​fgetc ([[cstdio.syn]](cstdio.syn "31.13.1 Header synopsis")) from the resource, as a binary file[.](#12.sentence-1) If any call to std​::​fgetc returns EOF, the program is ill-formed[.](#12.sentence-2) [13](#13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L951) *Recommended practice*: The value of each integer literal should closely represent the bit stream of the resource unmodified[.](#13.sentence-1) This can require an implementation to consider potential differences between translation and execution environments, as well as any other applicable sources of mismatch[.](#13.sentence-2) [*Example [2](#example-2)*: #include #include #include #include #include int main() {// If the file is the same as the resource in the translation environment, no assert in this program should fail.constexpr unsigned char d[] = {#embed }; const std::vector vec_d = {#embed }; constexpr std::size_t expected_size = sizeof(d); // same file in execution environment as was embedded std::ifstream f_source("data.dat", std::ios::binary | std::ios::in); unsigned char runtime_d[expected_size]; char* ifstream_ptr = reinterpret_cast(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);} — *end example*] [*Example [3](#example-3)*: int i = {#embed "i.dat"}; // well-formed if i.dat produces a single valueint i2 =#embed "i.dat" ; // also well-formed if i.dat produces a single valuestruct s {double a, b, c; struct { double e, f, g; } x; double h, i, j;}; s x = {// well-formed if the directive produces nine or fewer values#embed "s.dat"}; — *end example*] [14](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1012) A preprocessing directive of the form # embed [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1 Preamble [cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1 Preamble [cpp.pre]") (that does not match the previous form) is permitted[.](#14.sentence-1) The preprocessing tokens after embed in the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens)[.](#14.sentence-2) Then, an attempt is made to form a [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]") preprocessing token ([[lex.header]](lex.header "5.6 Header names")) from the whitespace and the characters of the spellings of the resulting sequence of preprocessing tokens immediately after embed; the treatment of whitespace is implementation-defined[.](#14.sentence-3) If the attempt succeeds, the directive with the so-formed [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]") is processed as specified for the previous form[.](#14.sentence-4) Otherwise, the program is ill-formed[.](#14.sentence-5) [*Note [2](#note-2)*: Adjacent [*string-literal*](lex.string#nt:string-literal "5.13.5 String literals [lex.string]")*s* are not concatenated into a single[*string-literal*](lex.string#nt:string-literal "5.13.5 String literals [lex.string]") (see the translation phases in [[lex.phases]](lex.phases "5.2 Phases of translation")); thus, an expansion that results in two [*string-literal*](lex.string#nt:string-literal "5.13.5 String literals [lex.string]")*s* is an invalid directive[.](#14.sentence-6) — *end note*] Any further processing as in normal text described for the previous form is not performed[.](#14.sentence-7) [*Note [3](#note-3)*: That is, processing as in normal text happens once and only once for the entire directive[.](#14.sentence-8) — *end note*] [*Example [4](#example-4)*: If the directive matches the second form, the whole directive is replaced[.](#14.sentence-9) If the directive matches the first form, everything after the name is replaced[.](#14.sentence-10) #define EMPTY#define X myfile#define Y rsc#define Z 42#embed prefix(Z)#embed EMPTY prefix(Z) is equivalent to:#embed prefix(42)#embed prefix(42) — *end example*]