---
title: "#embed offset parameter"
document: P3540R3
date: 2026-06-12
audience: CWG
reply-to:
  - "JeanHeyd Meneide <phdofthehouse@gmail.com>"
  - "Shepherd (Shepherd's Oasis LLC) <shepherd@soasis.org>"
---

## Changelog

### Revision 3 - June <sup>12th</sup>, 2026

- Slightly adjust the Intent section of the paper to be more clear.
- Move wording for resource-offset and resource-count jointly into [cpp.embed.gen] rather than having it in the [cpp.embed.param.offset] section.
- Clean up extraneous examples and tighten up the `static_assert`s/variable names of the `offset` examples.

### Revision 2 - June <sup>5th</sup>, 2025

- Design was expanded upon in Revision 1 and further explicated in this version to prevent people from being confused about what is being proposed here and what the specification was asking for. It was not recorded in the previous changelog: it is being recorded here.
- Revision 2 does not add or change any of the wording in a way that matters; it just fixes clerical errors, typos, and aligns dates.
- One such typo: fixes "It shall provide" to "It provides", as the "shall" is spurious in C++ wording since it does not provide anything.
- § 3 Design elaborates that this is meant to be that `offset` applies before `limit` is applied, as what is implemented in `clang::offset` and `gnu::offset` today.
- Some discussion during an SG22 meeting about restricting the order of embed parameters. This isn’t present in any implementation or in the C wording, and it’s an awful experience overall: rejected this design to proceed forward.

### Revision 1 - February 14<sup>th</sup>, 2025

- Minor typo and wording cleanup.

### Revision 0 - December 13<sup>th</sup>, 2024

- Initial release.

## Introduction and Motivation

The goal is to add the extremely-popular and already-implemented `gnu::offset` and `clang::offset` parameters as standard parameters. That is the only motivation of this proposal; to standardize existing practice.

Originally, users asked to add this parameter, but only after C23 standardized. Given the late stage that users have asked -- waiting until the very end -- it has to be added separately. This proposal aims to standardize what users have asked for, and what Clang and GCC have implemented.

## Design

The design of `offset(some-preprocessor-constant-value)` is straightforward:

- `offset` discards `some-preprocessor-constant-value` items, up to the full size of the resource;
- nothing happens if `some-preprocessor-constant-value` evaluates to `0`;
- if `offset` is greater than or equal to the size of the resource, the resource is considered empty;
- `limit` does not shrink the file to a given size before `offset`; `offset` is applied to the original file size (called the "implementation-resource-count" in the wording).

These are the only tenets of the design, and match the practice for existing implementations `gnu::offset` and `clang::offset`. It is also how the original author envisioned this when it was first PR’d to Clang, and the original tests (plus new ones) still pass in the LLVM/clang and gnu/gcc repositories.

There was some discussion during the June 4<sup>th</sup>, 2025 about the order of parameters. This turned into a significant enough change that it is a separate paper. No additional discussion or changes are proposed for this paper: it is exactly a standardization of existing practice and what was approved in Austria.

## Wording

This wording is relative to C++'s latest working draft.

### Intent

The intent of the wording is to provide a preprocessing directive that:

- allows an `offset` parameter skipping over a number of elements before beginning to write out elements to the comma-delimited list;
- and, applies to the actual size of the resource (i.e., before any applied `limit` parameter).

### Feature Test Macro

The feature test macro `__cpp_pp_embed` should be increased from `202502L` to `${PROPER_VALUE}`, where `PROPER_VALUE`. is determined by the Editors.

### Proposed Language Wording

#### Add to the *control-line* production in §15.1 Preamble [**cpp.pre**] a new grammar production for `offset`

> *embed-standard-parameter*:
> 
> : **limit** **(** *pp-balanced-token-seq* **)**
> 
> <ins>**offset** **(** *pp-balanced-token-seq* **)**</ins>
> 
> **prefix** **(** *pp-balanced-token-seq*<sub>*opt*</sub> **)**
> 
> **suffix** **(** *pp-balanced-token-seq*<sub>*opt*</sub> **)**
> 
> **if_empty** **(** *pp-balanced-token-seq*<sub>*opt*</sub> **)**

#### Modify and add paragraphs in §15.4.1 General [**cpp.embed.gen**]

> 15.4.1
> 
> General
> 
> [**cpp.embed.gen**]
> 
> ...
> 
> ...
> 
> A resource is a source of data accessible from the translation environment. A resource has an *implementation-resource-width*, which is the implementation-defined size in bits of the resource. If the *implementation-resource-width* is not an integral multiple of `CHAR_BIT`, the program is ill-formed. Let *implementation-resource-count* be implementation-resource-width divided by `CHAR_BIT`. <ins>Every resource has a *resource-offset*, which is</ins>
> 
> 
> 
> 
> the value as computed from the optionally-provided `offset` *embed-parameter* ([cpp.embed.param.offset]), if present;
> 
> otherwise, 0.
> 
> 
> 
> Every resource also has a *resource-count*, which is
> 
> - <ins> max ( min ( limit-value , implementation-resource-count - resource-offset ) , 0 ) if the `limit` *embed-parameter* ([[cpp.embed.param.limit](https://wg21.link/cpp.embed.param.limit)]) is present, where the value computed from the `limit` *embed-parameter* is *limit-value* </ins> <del>the value as computed from the optionally-provided `limit` *embed-parameter* ([[cpp.embed.param.limit](https://wg21.link/cpp.embed.param.limit)]), if present</del> ;
> - otherwise, <ins> max ( implementation-resource-count - resource-offset , 0 ) </ins> <del>the implementation-resource-count</del> .
> 
> A resource is empty if the resource-count is zero.
> 
> ...
> 
> ..
> 
> The integer literals in the comma-separated list correspond to resource-count consecutive calls to `std​::​fgetc` ([[cstdio.syn](https://wg21/link/cstdio.syn)]) from the resource, as a binary file.
> 
>  First, resource-offset calls to `std::fgetc` from the resource as a binary file have their result discarded and ignored. Next, resource-count consecutive calls to `std::fgetc` produce the elements of the comma-separated list of integer literals, in order. If any of the resource-count calls to `std​::​fgetc` returns `EOF`, the program is ill-formed.
> 
> If any call to `std​::​fgetc` returns `EOF`, the program is ill-formed.

#### Add a new sub-clause §15.4.2.✨ under Resource Inclusion for Embed parameters for the new `offset` parameter [**cpp.embed.param.offset**]

> 
> 
>  15.4.2.✨ `offset` parameter [**cpp.embed.param.offset**] 
> 
> An *embed-parameter* of the form `offset ( *pp-balanced-token-seq* )` denotes the number of elements to be skipped from the resource. It shall appear at most once in the *embed-parameter-seq*.
> 
> 
> The *pp-balanced-token-seq* is evaluated as a *constant-expression* using the rules as described in conditional inclusion ([[cpp.cond](https://wg21.link/cpp.cond)]), but without being processed as in normal text an additional time.
> 
> 
> The *constant-expression* shall be an integral constant expression whose value is greater than or equal to zero.
> 
> [*Example*:
> constexpr const unsigned char arr[] = {
>   // a hypothetical resource capable of expanding to
>   // four or more elements
> #embed <sdk/jump.wav>
> };
> 
> constexpr const unsigned char offset_arr[] = {
>   // the same hypothetical resource capable of expanding
>   // to four or more elements
> #embed <sdk/jump.wav> offset(2)
> };
> 
> constexpr const unsigned char offset_limit_arr[] = {
>   // the same hypothetical resource capable of expanding
>   // to four or more elements
> #embed <sdk/jump.wav> offset(1) limit(1)
> };
> 
> static_assert(arr[2] == offset_arr[0]);
> static_assert(arr[3] == offset_arr[1]);
> static_assert(arr[1] == offset_limit_arr[0]);
> 
> – *end example*]
> 
> 

### Remove the following text from [cpp.embed.param.limit], ❡3

> The *constant-expression* shall be an integral constant expression whose value is greater than or equal to zero. <del>The resource-count ([cpp.embed.gen]) becomes implementation-resource-count, if the value of the constant-expression is greater than implementation-resource-count; otherwise, the value of the constant-expression.</del>

### Add a new example to the `if_empty` embed parameter [cpp.embed.param.if.empty] section

> 
> [*Example*: Given a resource `<single_byte>` that has an implementation-resource-count of 1, the following directives:
> #embed <single_byte> offset(1) if_empty(42203)
> 
> are replaced with:
> 42203
> 
> – *end example*]
>
