# How to anonymously initialize a slice?

**URL:** <https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687>\
**Category:** Help\
**Tags:** language\
**Created:** [August 19, 2024, 4:57am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687 "2024-08-19T04:57:58Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [August 19, 2024, 4:57am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/1 "2024-08-19T04:57:59Z")

</div>

How do I do the following without the `byte` variable?

```zig
fn send_and_recv(data: []u8) void {
    std.debug.assert(data.len > 0);
    std.log.warn("Sent {any}", .{data});
    data[0] = 1;
}

test {
    var byte: [1]u8 = .{1};
    send_and_recv(&byte);
}

```

this gives a compile error

```zig
send_and_recv(&.{1});

```

```zig
src/main.zig:73:19: error: expected type '[]u8', found '*const [1]u8'
    send_and_recv(&.{1});

```

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [August 19, 2024, 5:16am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/2 "2024-08-19T05:16:20Z")

</div>

Hey again - so beyond allocating something in place (which would be a direct memory leak), you can’t.

Literals and pointers to literal things are always `const`. You can try to cheat fate with `@constCast` but that will have undefined behaviour because the underlying literal itself is constant.

Essentially, that memory has to live somewhere away from that call-site for it to be a mutable slice. If you dislike the aesthetics at it and it’s a small request, you can just return the array directly and copy out.

The thing is… to my eye… this _looks_ correct to me. The memory layout is clear, you can see the qualifiers clearly, etc… I’ve been writing Zig for a while and I’ve come to think of this as clear instead of verbose.

---

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [August 19, 2024, 5:25am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/3 "2024-08-19T05:25:41Z")

</div>

I mean my untrained eye would have expected `&.{1}` to be allocated on the stack just like `byte` is, but in the stack scope of `send_and_recv`, so `&.{1}` would disappear when send\_and\_recv returns.

(not sure if I am using the correct terms here but I hope that makes sense)

---

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [August 19, 2024, 5:28am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/4 "2024-08-19T05:28:28Z")

</div>

But I guess that would conflict with all mentions of `&.{1}` in my program sharing the same constant memory.

Maybe the compiler could give me separate instances when they are mutable?

---

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [August 19, 2024, 5:30am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/5 "2024-08-19T05:30:55Z")

</div>

The annoyance comes from me having to pick a name for something that I fundamentally don’t care about, and I would rather not double the number of functions in my API just so I can have a const parameter…

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [August 19, 2024, 5:34am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/6 "2024-08-19T05:34:10Z")

</div>

Yeah, I gotcha. I’m going to write out a few things that you are probably aware of but through the context of Zig.

Conceptually, based on the function you’ve provided, this isn’t even really doable by design.

```zig
pub something(data: []u8) void {
    data[0] = 1;
}

```

Say for example I could use some kind of “in situ” syntax:

```zig
something(mutable &[1]u8{ 0 }); 

```

Well… now what? How do I get my array back? That function returns `void` so I just kinda threw it down a hole. This may be because the example you’re posting is a simplified one but in this case, it’s really not understandable. Not trying to nitpick ya, but it’s hard to know what the goal is here.

* * *

Fundamentally, remember what a slice is - it’s a length and a pointer. Slices don’t contain stuff, they point to stuff and tell you how much stuff is there. So if I create a slice to something, it needs to be in a defined location.

Creating literals like in your example actually _does_ put it somewhere! It’s just in data segment of your binary. If you want to see this in action, please read this thread: [Diving deep into anonymous struct literals - #3 by bnl1](https://ziggit.dev/t/diving-deep-into-anonymous-struct-literals/2931/3)

So as it stands, as far as slices are concerned, I don’t think this really makes sense. Hopefully you get what I’m driving at here.

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [August 19, 2024, 5:41am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/7 "2024-08-19T05:41:16Z")

</div>

Okay, tell me if I am wrong here - is your intention _not_ to modify an array that the caller holds onto, but instead give your function the memory that it’s going to work on? Hence the `void` returning function?

---

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [August 19, 2024, 5:47am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/8 "2024-08-19T05:47:05Z")

</div>

The void was a simplification, the true use case is to enable a zero-allocation API. The data I am providing the function is both sent over a network interface and used as the memory area to de-serialize data into on the response.

```zig
fn send_and_recv(*port: Port, data: []u8, timeout_us: u32) !u16 {
    
    // send data (ethernet frame) through a ring of subdevices, returning back to me on the same network interface
    try port.send(data)

    // recv the data back, modified by the devices.
    // we recv that data back into the "data" parameter so that
    // we can have a zero-allocation API (recv'd data is always the same size as sent data)
    // the devices that did something increment a counter in the frame that is used
    // as a basic check that everything is ok
    // this is called the working counter "wkc"

    const wkc: u16 = try port.recv_with_timeout(data, timeout_us)
    return wkc
}

test {

    // in this scenario, we don't care what the subdevices did to the frame
    // other than the working counter
    var byte: [1]u8 = .{1};
    const wkc = try send_and_recv(&byte);

    if (wkc == 0) {
        // uh oh! maybe the ethernet cable broke or a subdevice lost power!
        // do something about it!
        handle_subdevice_error();
    }
}

```

---

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [August 19, 2024, 5:51am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/9 "2024-08-19T05:51:13Z")

</div>

> [@AndrewCodeDev](#):
>
> Okay, tell me if I am wrong here - is your intention _not_ to modify an array that the caller holds onto, but instead give your function the memory that it’s going to work on?

Exactly, for a zero-allocation API

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [August 19, 2024, 5:53am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/10 "2024-08-19T05:53:06Z")

</div>

That example definitely helps - now I get your issue. Please clarify one more thing for me. How big is that `data` object pointhing to in bytes usually? Is there a ceiling? I have a few suggestions but I want to make sure I’m on track.

---

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [August 19, 2024, 6:04am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/11 "2024-08-19T06:04:40Z")

</div>

Basic operation is the following:

1. Send frames into the ring.
2. Recv frames back from the ring.

The details come into play when you want to have multiple frames “in flight”.

The protocol has an `idx` byte in the frame that I can use to identify the frames with so I can re-order un-ordered frames should they occur (some NIC’s have the potential to re-order frames when there are mulitple in their recv buffer). This means you can have a max number of 128 identified simultaneous frames in flight.

So in more detail:

1. Send frames (each frame always less than 1514 bytes). Use unique idx for each.
2. Recv frames, identify each using idx and deserailize them into appropriate memory areas.

My first pass at the API was that I allocated memory in the `port` struct to enable 128 frames, but then I figured out I could just give the port the memory it needed from the stack for each call to `send_and_recv` (there are `mutex`’s inside the `port` to make sure each frame receives a unique `idx`)

---

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [August 19, 2024, 6:06am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/12 "2024-08-19T06:06:53Z")

</div>

This is the “send\_and\_recv” function

> <https://github.com/kj4tmp/zecm/blob/main/src/nic.zig#L668>

Aren’t proprietary esoteric protocols fun! 🙂

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [August 19, 2024, 6:14am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/13 "2024-08-19T06:14:40Z")

</div>

Okay, so if it were me designing this, I’d split that data argument into two arguments - one for `send` and one for `recv` (or something like that). You wouldn’t have to change much, but here’s why I’m saying this: it would achieve the behavior you’re looking for, afford another option, and even keep the same implementation you have now. I’m just going to focus on the slice arguments:

```zig
pub fn send_and_recv(send: []const u8, recv: ?[]u8) !u16...

```

In this case, I can get the same behaviour currently with the following:

```zig
// send and read to the same buffer
const wkc = try send_and_recv(data[0..], data[0..]);
// only send and don't read because we don't care
const wkc = try send_and_recv(&.{1}, null);
// or send/recv on different buffers
const wkc = try send_and_recv(send[0..], recv[0..]);

```

The issue you’re hitting is a design problem and think it’s annoying you because something is bugging you on a fundamental level here. Since that one argument has a duel purpose, you lose the ability to just send literal data. However, you can make two arguments have a singular purpose by making them both the same and split the difference too.

---

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [August 19, 2024, 6:20am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/14 "2024-08-19T06:20:25Z")

</div>

This is a great suggestion!!

I will definitely change to this dual argument approach.

And for another reason too, I was getting annoyed when I wanted to send the same data twice, because the data would get modified on receipt, so I had to re-declare the data to send etc.

Thanks!

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [August 19, 2024, 6:21am UTC](https://ziggit.dev/t/how-to-anonymously-initialize-a-slice/5687/15 "2024-08-19T06:21:32Z")

</div>

Absolutely - you can even dispatch to optimized algorithms for one or the other using `if (send.ptr == recv.ptr)`… could be some interesting optimizations there 🙂
