# How to create a memory region at compile time and have part of it embedded in the program binary?

**URL:** <https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879>\
**Category:** Help\
**Tags:** language, comptime\
**Created:** [January 9, 2026, 5:15pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879 "2026-01-09T17:15:03Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![UnknowZigger](https://ziggit.dev/letter_avatar_proxy/v4/letter/u/cab0a1/32.png) [@UnknowZigger](https://ziggit.dev/u/UnknowZigger)\
**Post date:** [January 9, 2026, 5:15pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/1 "2026-01-09T17:15:03Z")

</div>

just a case

```zig

fn do() void {
    const str = comptime str: {
        errdefer unreachable;
        var buf: [256]u8 = undefined;
        const result = try std.fmt.bufPrint(&buf, "{s}", .{"xxx"}); // edit memory region
        break :str result;
    };
    std.debug.print("{s}\n", .{str});
}

```

but compile failed

```zig
error: runtime value contains reference to comptime var
    std.debug.print("{s}\n", .{str});

```

UPDATE: This is just a simple example to get the code running—don’t worry about how to print strings at compile time.

---

<div class="post-metadata">

**Author:** ![UnknowZigger](https://ziggit.dev/letter_avatar_proxy/v4/letter/u/cab0a1/32.png) [@UnknowZigger](https://ziggit.dev/u/UnknowZigger)\
**Post date:** [January 9, 2026, 5:33pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/2 "2026-01-09T17:33:17Z")

</div>

I’ve found a way that works. Is this the right thing to do?

```zig
fn do() void {
    const str = comptime str: {
        errdefer unreachable;
        var buf: [256]u8 = undefined;
        const buf_str = try std.fmt.bufPrint(&buf, "{s}", .{"xxx"});
        var result: [buf_str.len]u8 = undefined;
        std.mem.copyForwards(u8, &result, buf_str);
        break :str result;
    };
    std.debug.print("{s}\n", .{str});
}

```

---

<div class="post-metadata">

**Author:** ![D-Berg](https://ziggit.dev/user_avatar/ziggit.dev/d-berg/32/4195_2.png) [@D-Berg](https://ziggit.dev/u/D-Berg)\
**Post date:** [January 9, 2026, 5:34pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/3 "2026-01-09T17:34:15Z")

</div>

You can just make it a global variable.

```zig
const str = ”xxx”; 
fn do() void {
    std.debug.print("{s}\n", .{str});
}

```

---

<div class="post-metadata">

**Author:** ![ForeverZer0](https://ziggit.dev/user_avatar/ziggit.dev/foreverzer0/32/2443_2.png) [@ForeverZer0](https://ziggit.dev/u/ForeverZer0)\
**Post date:** [January 9, 2026, 5:38pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/4 "2026-01-09T17:38:44Z")

</div>

If your use-case is simply a comptime formatted string, `std.fmt.` has a comptime function for this.

```zig
const std = @import("std");

const str = std.fmt.comptimePrint("{s}", .{"xxx"});

pub fn main() !void {
    std.debug.print("{s}\n", .{str});
}

```

Your code is failing because `buf` only has a scope for the block it is within.

---

<div class="post-metadata">

**Author:** ![UnknowZigger](https://ziggit.dev/letter_avatar_proxy/v4/letter/u/cab0a1/32.png) [@UnknowZigger](https://ziggit.dev/u/UnknowZigger)\
**Post date:** [January 9, 2026, 5:41pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/5 "2026-01-09T17:41:19Z")

</div>

I know about `std.fmt.comptimePrint`; it’s just an example of manipulating memory.

---

<div class="post-metadata">

**Author:** ![LucasSantos91](https://ziggit.dev/user_avatar/ziggit.dev/lucassantos91/32/440_2.png) [@LucasSantos91](https://ziggit.dev/u/LucasSantos91)\
**Post date:** [January 9, 2026, 5:49pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/6 "2026-01-09T17:49:33Z")

</div>

Yes this is the right approach.  
FYI, you should use `@memcpy` here instead of `copyForwards`.

---

<div class="post-metadata">

**Author:** ![grayhatter](https://ziggit.dev/letter_avatar_proxy/v4/letter/g/73ab20/32.png) [@grayhatter](https://ziggit.dev/u/grayhatter)\
**Post date:** [January 9, 2026, 6:02pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/7 "2026-01-09T18:02:05Z")

</div>

You asked what the right thing to do was. `comptimePrint` is the correct way to express this code.

But for things like this, (that can’t be expressed as a print statement) I’ve taken to putting all the code in a function, and `const name = comptime realFunction();` I find it’s easier to reason about over `thing = comptime brk: { [some inline block] };`

Other than that, I’d probably read the zig docs about both arrays as a whole, and static local variables. Because most everything (that’s not runtime allocated) are all “embedded memory” within the binary. And, importantly as the docs say:

> Zig programmers must always be able to answer the question: [Where are the bytes?](https://ziglang.org/documentation/master/#Where-are-the-bytes)

So knowing how to get the kind you want, and where they live is an important aspect of zig. 🙂

---

<div class="post-metadata">

**Author:** ![UnknowZigger](https://ziggit.dev/letter_avatar_proxy/v4/letter/u/cab0a1/32.png) [@UnknowZigger](https://ziggit.dev/u/UnknowZigger)\
**Post date:** [January 9, 2026, 6:35pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/8 "2026-01-09T18:35:42Z")

</div>

Thank you for your suggestion. I’m perfectly clear about where the “bytes” are. The point of my post isn’t about embedding binary data, but rather how to solidify a portion of data in compile-time memory.

---

<div class="post-metadata">

**Author:** ![grayhatter](https://ziggit.dev/letter_avatar_proxy/v4/letter/g/73ab20/32.png) [@grayhatter](https://ziggit.dev/u/grayhatter)\
**Post date:** [January 9, 2026, 6:51pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/9 "2026-01-09T18:51:53Z")

</div>

> [@UnknowZigger](#):
>
> I’m perfectly clear about where the “bytes” are.

Are you sure? Because in your title post, `var buf`, which is where you printed the string, goes “out of scope” when you reach the `break :str` so `const result` is pointing to a memory location that you don’t control anymore. Knowing where the bytes are means you have to know when you have a slice vs when you have an array. `comptimePrint` is the correct way to write this, because it doesn’t return a pointer to the memory. It returns an array of bytes, similar to how you found copying the data to `var result: [buf_str.len]u8` works. Because you’re creating an array of a defined size. And then copying the printed string into it, (and then possibly copying those bytes a 3rd time when `result` is moved to `str`. (But to be fair, the compiler is likely to figure that out, and omit one or both copies).

> [@UnknowZigger](#):
>
> but rather how to solidify a portion of data in compile-time memory.

But The way to create a const block of memory, based on comptime logic, is inline with your second code block. Calculate the array size needed, write the data into the var array at comptime, and then copy that data into a const array of the same size. The code in `comptimePrint` is a slightly better version of your 2nd example.

---

<div class="post-metadata">

**Author:** ![UnknowZigger](https://ziggit.dev/letter_avatar_proxy/v4/letter/u/cab0a1/32.png) [@UnknowZigger](https://ziggit.dev/u/UnknowZigger)\
**Post date:** [January 9, 2026, 7:15pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/10 "2026-01-09T19:15:07Z")

</div>

> [@grayhatter](#):
>
> Are you sure? Because in your title post, `var buf`, which is where you printed the string, goes “out of scope” when you reach the `break :str` so `const result` is pointing to a memory location that you don’t control anymore. Knowing where the bytes are means you have to know when you have a slice vs when you have an array. `comptimePrint` is the correct way to write this, because it doesn’t return a pointer to the memory. It returns an array of bytes, similar to how you found copying the data to `var result: [buf_str.len]u8` works. Because you’re creating an array of a defined size. And then copying the printed string into it, (and then possibly copying those bytes a 3rd time when `result` is moved to `str`. (But to be fair, the compiler is likely to figure that out, and omit one or both copies).

That’s because I naïvely assumed the compiler could infer my intention of needing the `result` data and would therefore automatically create a piece of data to serve as the value of `str`, while letting `buf` simply disappear.

---

<div class="post-metadata">

**Author:** ![grayhatter](https://ziggit.dev/letter_avatar_proxy/v4/letter/g/73ab20/32.png) [@grayhatter](https://ziggit.dev/u/grayhatter)\
**Post date:** [January 9, 2026, 7:32pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/11 "2026-01-09T19:32:09Z")

</div>

Yeah, I know what you mean. It’s both a blessing and a curse that zig refuses to try to guess what you want. On the plus side, you don’t have to wonder if you’re gonna get all 256 bytes stored “somewhere” in your program, for the comptime created slice, or even just 3, because the compiler figured out you only use 3. But on the down side, you have to specify explicitly what you want, and exactly where you want it to live. But then, I don’t really consider that a down side.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://ziggit.dev/user_avatar/ziggit.dev/mnemnion/32/2478_2.png) [@mnemnion](https://ziggit.dev/u/mnemnion)\
**Post date:** [January 9, 2026, 11:36pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/12 "2026-01-09T23:36:31Z")

</div>

> [@UnknowZigger](#):
>
> Is this the right thing to do?

It’s one way to do it, here’s another:

```zig
test "constant comptime memory" {
    const str = comptime str: {
        errdefer unreachable;
        var buf: [256]u8 = undefined;
        const result = try std.fmt.bufPrint(&buf, "{s}", .{"xxx"}); // edit memory region
        const res_buf: [result.len]u8 = result[0..result.len].*;
        break :str res_buf;
    };
    std.debug.print("{s}\n", .{str});
}

```

> [@grayhatter](#):
>
> You asked what the right thing to do was.

He asked how to create a memory region at compile time. This kind of thing generalizes, `comptimePrint` does not.

---

<div class="post-metadata">

**Author:** ![chung-leong](https://ziggit.dev/user_avatar/ziggit.dev/chung-leong/32/999_2.png) [@chung-leong](https://ziggit.dev/u/chung-leong)\
**Post date:** [January 10, 2026, 12:08am UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/13 "2026-01-10T00:08:51Z")

</div>

Your code would actually work way back in Zig 0.11.0 ([Godbolt](https://godbolt.org/z/bKqnnKcq6)). The subsequent version introduced restrictions on usage of comptime pointers, forbiddening them from being seen in runtime or outside their scopes. Now, whenever you have a slice in comptime, you need to copy its content into an array first:

```zig
fn do() void {
    const str = comptime str: {
        var buf: [256]u8 = undefined;
        const result = std.fmt.bufPrint(&buf, "{s}", .{"xxx"}) catch unreachable;
        var array: [result.len]u8 = undefined;
        @memcpy(&array, result);
        break :str array;
    };
    std.debug.print("{s}\n", .{str});
}

```

In this case, `comptimePrint()` obviously exists so you can just use that.

---

<div class="post-metadata">

**Author:** ![squeek502](https://ziggit.dev/user_avatar/ziggit.dev/squeek502/32/409_2.png) [@squeek502](https://ziggit.dev/u/squeek502)\
**Post date:** [January 10, 2026, 1:26pm UTC](https://ziggit.dev/t/how-to-create-a-memory-region-at-compile-time-and-have-part-of-it-embedded-in-the-program-binary/13879/14 "2026-01-10T13:26:01Z")

</div>

More context here:

> [@Comptime-Mutable Memory Changes](https://ziggit.dev/t/comptime-mutable-memory-changes/3702):
>
> Hi everyone! Recently, PR [#19414](https://github.com/ziglang/zig/pull/19414) was merged, which more-or-less rewrote the compiler’s internal implementation of comptime var. This rewrite comes with some language changes, so I thought I’d explain the user-facing impact of this PR here so that people know what’s going on when they inevitably get errors TL;DR A pointer to a comptime var is never allowed to become runtime-known, to be contained within the resolved value of a declaration, or to be otherwise referenced by analysis of any declara…
