# Struct method reference to \`self\` by pointer or not?

**URL:** <https://ziggit.dev/t/struct-method-reference-to-self-by-pointer-or-not/9677>\
**Category:** Help\
**Tags:** language, packed-structs\
**Created:** [April 17, 2025, 8:29am UTC](https://ziggit.dev/t/struct-method-reference-to-self-by-pointer-or-not/9677 "2025-04-17T08:29:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dbushell](https://ziggit.dev/user_avatar/ziggit.dev/dbushell/32/4741_2.png) [@dbushell](https://ziggit.dev/u/dbushell)\
**Post date:** [April 17, 2025, 8:29am UTC](https://ziggit.dev/t/struct-method-reference-to-self-by-pointer-or-not/9677/1 "2025-04-17T08:29:26Z")

</div>

Kinda a basic question but a little context:

I’m parsing a UDP packet as a struct called `Packet` that copies and allocates the bytes into `buf` like:

```zig
const Self = @This();

buf: []const u8 = undefined,
header: *Header = undefined,

pub fn initBuffer(allocator: Allocator, src: []const u8) !Self {
    const buf = try allocator.alloc(u8, src.len);
    errdefer allocator.free(buf);
    @memcpy(buf[0..], src);
    const packet: Self = .{
        .buf = buf,
        .header = @ptrCast(@alignCast(buf[0..min_packet_size])),
    };}

```

See full source: [Github: Packet.zig](https://github.com/dbushell/zun/blob/227524995f3a61a37ef614f32797703483a7cde1/src/Packet.zig#L76C54-L76C56)

The header (first 36 bytes) goes into an internal `packed struct` called `Header`.

I have some methods on the struct to read/parse the header values.

I understand for primitive values I can use `self`:

```zig
/// Packet byte length (header + payload)
pub fn size(self: Self) u16 {
    return self.header.size;
}

```

and the compiler optimises whether or not `self` is copied, I don’t need to care, right?

My question is do I need to care when returning a pointer? For example:

```zig
/// Device MAC address
pub fn target(self: Self) *const [6]u8 {
    return std.mem.asBytes(&self.header.target)[0..6];
}

```

Do I use `self: Self` or `self: *Self`?

I think the first is correct because I’m not mutating `self` and `self.header` is already a pointer to allocated memory. I’m not returning a stack pointer, right?

Thanks!

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [April 17, 2025, 8:53am UTC](https://ziggit.dev/t/struct-method-reference-to-self-by-pointer-or-not/9677/2 "2025-04-17T08:53:59Z")

</div>

in this case it doesnt matter since you are accessing a field which itself is a pointer and doing nothing else.

> [@dbushell](#):
>
> and the compiler optimises whether or not `self` is copied, I don’t need to care, right?

no, zig previously did that, i dont recall if it still does that, but if it does it will probably be removed soon. That optimisation is simply very troublesome to do since the compiler has no knowledge of the programmer’s intentions

---

<div class="post-metadata">

**Author:** ![rpkak](https://ziggit.dev/letter_avatar_proxy/v4/letter/r/a4c791/32.png) [@rpkak](https://ziggit.dev/u/rpkak)\
**Post date:** [April 17, 2025, 8:56am UTC](https://ziggit.dev/t/struct-method-reference-to-self-by-pointer-or-not/9677/3 "2025-04-17T08:56:23Z")

</div>

As long as the returned pointer is valid outside the function (which a pointer to `self` is not but the pointer `self.header` is) this seems to be fine.

I personally always try to avoid passing `self` by value and use `*const Self` (or `*Self`) instead (at least if `self` is not something like an enum or similar), because this also helps to avoid problems like [this](https://github.com/ziglang/zig/issues/23471).

---

<div class="post-metadata">

**Author:** ![dbushell](https://ziggit.dev/user_avatar/ziggit.dev/dbushell/32/4741_2.png) [@dbushell](https://ziggit.dev/u/dbushell)\
**Post date:** [April 17, 2025, 9:40am UTC](https://ziggit.dev/t/struct-method-reference-to-self-by-pointer-or-not/9677/4 "2025-04-17T09:40:01Z")

</div>

thanks for the additional info, that’s good to know

---

<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:** [April 17, 2025, 2:56pm UTC](https://ziggit.dev/t/struct-method-reference-to-self-by-pointer-or-not/9677/5 "2025-04-17T14:56:05Z")

</div>

The optimization is going to be removed, so follow the same rule as C: if a value is small enough (around 3 pointers), pass by value, otherwise by pointer.  
That is assuming that a value is valid in the first place. If you’re returning a pointer to something inside the parameter, you need to pass a pointer.
