# Inline/comptime: weird results

**URL:** <https://ziggit.dev/t/inline-comptime-weird-results/10298>\
**Category:** Help\
**Tags:** language\
**Created:** [May 28, 2025, 8:03pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298 "2025-05-28T20:03:00Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![charlie](https://ziggit.dev/user_avatar/ziggit.dev/charlie/32/1930_2.png) [@charlie](https://ziggit.dev/u/charlie)\
**Post date:** [May 28, 2025, 8:03pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/1 "2025-05-28T20:03:00Z")

</div>

Finally managed to get this to work, but it feels like `inline` should not be necessary here: [ghext/src/ghext.zig at 111d78439b0d3ce885a5205ace1933e91724334f · charlesrocket/ghext · GitHub](https://github.com/charlesrocket/ghext/blob/111d78439b0d3ce885a5205ace1933e91724334f/src/ghext.zig#L142-L167)

without `inline` I am getting cast errors or unresolved comptime

```zig
src/ghext.zig:216:21: error: expected type '*ghext', found '*const ghext'
    const head = ghx.hash(HashLen.Short, Worktree.Unchecked);
                 ~~~^~~~~
src/ghext.zig:216:21: note: cast discards const qualifier
src/ghext.zig:142:19: note: parameter type declared here
pub fn hash(self: *Ghext, comptime length: HashLen, check: Worktree) []const u8 {
                  ^ ~~~~~

```

---

<div class="post-metadata">

**Author:** ![charlie](https://ziggit.dev/user_avatar/ziggit.dev/charlie/32/1930_2.png) [@charlie](https://ziggit.dev/u/charlie)\
**Post date:** [May 28, 2025, 8:07pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/2 "2025-05-28T20:07:33Z")

</div>

If `inline` is removed, only one (`hash_short`) test is passing.

---

<div class="post-metadata">

**Author:** ![dimdin](https://ziggit.dev/user_avatar/ziggit.dev/dimdin/32/1457_2.png) [@dimdin](https://ziggit.dev/u/dimdin)\
**Post date:** [May 28, 2025, 8:09pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/3 "2025-05-28T20:09:24Z")

</div>

Since the `hash` function does not modify `self` you can fix the error by changing `pub fn hash(self: *Ghext,...` to `pub fn hash(self: *const Ghext,...`

---

<div class="post-metadata">

**Author:** ![charlie](https://ziggit.dev/user_avatar/ziggit.dev/charlie/32/1930_2.png) [@charlie](https://ziggit.dev/u/charlie)\
**Post date:** [May 28, 2025, 8:16pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/4 "2025-05-28T20:16:41Z")

</div>

Nope, it only works with `inline`. If I drop it and enforce `const`:

```zig
src/ghext.zig:155:17: error: unable to resolve comptime value
                head ++ "-unverified"
                ^~~~
src/ghext.zig:155:17: note: slice being concatenated must be comptime-known

```

---

<div class="post-metadata">

**Author:** ![permutationlock](https://ziggit.dev/user_avatar/ziggit.dev/permutationlock/32/9958_2.png) [@permutationlock](https://ziggit.dev/u/permutationlock)\
**Post date:** [May 28, 2025, 8:37pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/5 "2025-05-28T20:37:10Z")

</div>

The `++` concatenation operation concatenates arrays. You are attempting to use it to concatenate slices and return a slice, which does not work. Even in the `Short` case where your slices have comptime length, where will the memory for the concatenated slices live? The only reason it is currently working with inline is because you are calling the function with `Unchecked` and thus the concatenation portion is not being evaluted. If you call the current inline version with `Checked` then you get the same compile error.

---

<div class="post-metadata">

**Author:** ![charlie](https://ziggit.dev/user_avatar/ziggit.dev/charlie/32/1930_2.png) [@charlie](https://ziggit.dev/u/charlie)\
**Post date:** [May 28, 2025, 9:12pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/6 "2025-05-28T21:12:55Z")

</div>

`Checked` also works, but only `hash_short` is passing. `++` / `**` works for both slices and arrays.

---

<div class="post-metadata">

**Author:** ![charlie](https://ziggit.dev/user_avatar/ziggit.dev/charlie/32/1930_2.png) [@charlie](https://ziggit.dev/u/charlie)\
**Post date:** [May 28, 2025, 9:30pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/7 "2025-05-28T21:30:51Z")

</div>

Added more tests (Checked + Unchecked) and now getting unresolved comptime with `inline` as well 🤕

---

<div class="post-metadata">

**Author:** ![Justus2308](https://ziggit.dev/user_avatar/ziggit.dev/justus2308/32/5305_2.png) [@Justus2308](https://ziggit.dev/u/Justus2308)\
**Post date:** [May 28, 2025, 9:31pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/8 "2025-05-28T21:31:36Z")

</div>

I suspect that `hash_short` is passing because `self.head[0..7]` coerces to `*const [7]u8` so the compiler knows how much memory `head ++ "..."` will take up at comptime. It can’t know that when the length of `self.head` is runtime-known.

As permutationlock has already said, you can’t use `++` on a slice with runtime known length because where would you store it? The compiler would have to reserve `std.math.maxInt(usize) + "...".len` bytes for your concatenation to cover every possible length and that isn’t possible/feasible.

I’m surprised that this code works with `inline` probably there’s some lazy compilation magic going on there.

Generally you can use `std.mem.concat()` instead of `++` to make this work, of course this requires an allocator. But since you’re dealing with commit hashes here which have a fixed length you can also just use a `std.BoundedArray` or something similiar.

---

<div class="post-metadata">

**Author:** ![charlie](https://ziggit.dev/user_avatar/ziggit.dev/charlie/32/1930_2.png) [@charlie](https://ziggit.dev/u/charlie)\
**Post date:** [May 28, 2025, 9:39pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/9 "2025-05-28T21:39:50Z")

</div>

`self.head` is also comptime. But I guess I am introducing a mutation somewhere down the line.  
The idea is to pull a commit hash to append to a version string, so everything must be comptime. Ill check the BoundedArray, thanks! Tho, the issue is still quite confusing because it should never work as far as I can tell. But it does, in some cases.

---

<div class="post-metadata">

**Author:** ![Justus2308](https://ziggit.dev/user_avatar/ziggit.dev/justus2308/32/5305_2.png) [@Justus2308](https://ziggit.dev/u/Justus2308)\
**Post date:** [May 28, 2025, 9:42pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/10 "2025-05-28T21:42:50Z")

</div>

How is `self.head` comptime? You’re getting it from a child process at runtime or am I missing something?

---

<div class="post-metadata">

**Author:** ![charlie](https://ziggit.dev/user_avatar/ziggit.dev/charlie/32/1930_2.png) [@charlie](https://ziggit.dev/u/charlie)\
**Post date:** [May 28, 2025, 9:46pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/11 "2025-05-28T21:46:03Z")

</div>

When I mark it as comptime compiler complains about the redundancy. Maybe I pay too much attention to the compiler complaints. The init function uses a var to return a comptime struct, or at least thats the idea (`const head = try arr.toOwnedSlice();`). `readWithGit()` should be done in comptime and it worked so far. Maybe theres something else going on there.

---

<div class="post-metadata">

**Author:** ![permutationlock](https://ziggit.dev/user_avatar/ziggit.dev/permutationlock/32/9958_2.png) [@permutationlock](https://ziggit.dev/u/permutationlock)\
**Post date:** [May 28, 2025, 9:52pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/12 "2025-05-28T21:52:54Z")

</div>

I am surprised that you can concatenate slices with runtime contents and comptime length. You have to be very careful where you use that because it is “silently” using a single location in static memory (or maybe its on the stack and this illegal/undefined behavior?).

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

fn foo(slice: []const u8) []const u8 {
    return slice[0..8] ++ " \\";
}

test {
    const str = "hello this is a string";
    const foo_res = foo(str);
    try std.testing.expectEqualSlices(u8, "hello th \\", foo_res);
    const foo_res2 = foo("I hope this doesn't overwrite my first string");
    try std.testing.expectEqualSlices(u8, "I hope t \\", foo_res2, );
    try std.testing.expectEqualSlices(u8, "hello th \\", foo_res);
}

```

---

<div class="post-metadata">

**Author:** ![charlie](https://ziggit.dev/user_avatar/ziggit.dev/charlie/32/1930_2.png) [@charlie](https://ziggit.dev/u/charlie)\
**Post date:** [May 28, 2025, 9:55pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/13 "2025-05-28T21:55:42Z")

</div>

Yea I am kinda lost too) For some reason everything worked like a clock until I decided to handle both long and short hashes via `hash()`.

---

<div class="post-metadata">

**Author:** ![Justus2308](https://ziggit.dev/user_avatar/ziggit.dev/justus2308/32/5305_2.png) [@Justus2308](https://ziggit.dev/u/Justus2308)\
**Post date:** [May 28, 2025, 9:58pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/14 "2025-05-28T21:58:04Z")

</div>

Where exactly does the compiler complain about that? As soon as you use an allocator a value cannot be comptime anymore (unless your allocator works at comptime as well which `std.testing.allocator` does not) because the memory allocated by the allocator comes from the OS at runtime and cannot be known to the compiler. As far as I’m aware Zig also can’t execute child processes at comptime.  
Try explicitly forcing comptime with `var ghx = comptime try Ghext.init(std.testing.allocator);` it won’t compile.

---

<div class="post-metadata">

**Author:** ![Justus2308](https://ziggit.dev/user_avatar/ziggit.dev/justus2308/32/5305_2.png) [@Justus2308](https://ziggit.dev/u/Justus2308)\
**Post date:** [May 28, 2025, 10:01pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/15 "2025-05-28T22:01:03Z")

</div>

> [@permutationlock](#):
>
> (or maybe its on the stack and this illegal/undefined behavior?)

Yeah I think this returns a dangling stack pointer. String literals are usually stored in `.rodata` AFAIK and you can’t exactly do that with a runtime-known slice/array pointer. Although in your example this might actually be the case because all values are comptime-known.

EDIT: just confirming this:

```zig
const literal = "asdhfjklsadfhsdjklafhsdajfklsahdfljksadhfkhaksjr"; // 48 chars

export fn concat(slc: *const [8]u8) *const [8 + literal.len]u8 {
    return slc ++ literal;
}

export fn use(slc: *const [8]u8) u32 {
    const str = slc ++ literal;
    var result: u32 = 0;
    for (0..str.len - 8) |i| {
        for (str[i..][0..8]) |c| result += c;
    }
    return result;
}

```

With `-O ReleaseFast -mcpu x86_64`:

```zig
concat:
// doesn't even perform concatenation, just returns stack pointer
        push rbp
        mov rbp, rsp
        lea rax, [rbp - 57]
        pop rbp
        ret

```

```zig
use:
        push rbp
// copy slc param to stack[-56..-48]
        mov rbp, rsp
        mov rax, qword ptr [rdi]
        mov qword ptr [rbp - 56], rax
// copy literal to stack[-48..0]
        movups xmm0, xmmword ptr [rip + __anon_194]
        movups xmmword ptr [rbp - 48], xmm0
        movups xmm0, xmmword ptr [rip + __anon_194+16]
        movups xmmword ptr [rbp - 32], xmm0
        movdqu xmm0, xmmword ptr [rip + __anon_194+31]
        movdqu xmmword ptr [rbp - 17], xmm0

        [... loop etc ...]

        pop rbp
        ret

__anon_194:
        .asciz "asdhfjklsadfhsdjklafhsdajfklsahdfljksadhfkhaksjr"

```

([godbolt](https://godbolt.org/z/19bPMh64f))

Apparently the `++` indeed concatenates the slices on the stack.

---

<div class="post-metadata">

**Author:** ![charlie](https://ziggit.dev/user_avatar/ziggit.dev/charlie/32/1930_2.png) [@charlie](https://ziggit.dev/u/charlie)\
**Post date:** [May 28, 2025, 10:05pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/16 "2025-05-28T22:05:46Z")

</div>

Yea that makes sense about the allocator. It complains if I do `head: comptime []const u8,`

---

<div class="post-metadata">

**Author:** ![Justus2308](https://ziggit.dev/user_avatar/ziggit.dev/justus2308/32/5305_2.png) [@Justus2308](https://ziggit.dev/u/Justus2308)\
**Post date:** [May 28, 2025, 10:09pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/17 "2025-05-28T22:09:14Z")

</div>

> [@charlie](#):
>
> `head: comptime []const u8,`

The `comptime` only applies to the type here and since types are always comptime-known it is indeed redundant. You would have to do `comptime head: []const u8,` then the compiler would complain that you have to supply an initial comptime-known value for `head` (which would be immutable at runtime) or pass `head` as a separate `comptime` parameter to your functions.

But you probably don’t want `head` to be comptime here anyways because then you would have to recompile your entire program every time you want to use it.

---

<div class="post-metadata">

**Author:** ![charlie](https://ziggit.dev/user_avatar/ziggit.dev/charlie/32/1930_2.png) [@charlie](https://ziggit.dev/u/charlie)\
**Post date:** [May 28, 2025, 10:45pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/18 "2025-05-28T22:45:56Z")

</div>

Thats kinda the idea; I need that hash of the last commit appended to a version string only when I build the application. But now I am not sure if its doable with `git` binary. But I need it to be able to get hashes when the application does not have `.git` directory (bsd ports builds, etc).

---

<div class="post-metadata">

**Author:** ![Justus2308](https://ziggit.dev/user_avatar/ziggit.dev/justus2308/32/5305_2.png) [@Justus2308](https://ziggit.dev/u/Justus2308)\
**Post date:** [May 28, 2025, 10:56pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/19 "2025-05-28T22:56:51Z")

</div>

Ah sorry I’ve missed until now that your code is supposed to be called from a build script. In that case why not use the `std.Build` API, e.g. `std.Build.addSystemCommand()`?  
`head` also doesn’t have to be comptime-known within your code, it only needs to be comptime-known from the perspective of the code compiled by the build script, which it will be if it is generated during the build process.

---

<div class="post-metadata">

**Author:** ![charlie](https://ziggit.dev/user_avatar/ziggit.dev/charlie/32/1930_2.png) [@charlie](https://ziggit.dev/u/charlie)\
**Post date:** [May 28, 2025, 10:59pm UTC](https://ziggit.dev/t/inline-comptime-weird-results/10298/20 "2025-05-28T22:59:26Z")

</div>

The build script is one option. I also want to cover usage from within the application via same `hash()`. Tho, maybe I should drop that idea about non-build script use case.

[Next page](https://ziggit.dev/t/inline-comptime-weird-results/10298.md?page=2)
