#Question about return semantics

1 messages · Page 1 of 1 (latest)

strong yarrow
#

Hey all, hoping someone can help me understand how zig returns values. I wrote up a test case to help me understand and I'm confused by the results:

fn getFromList(list: *ArrayList(u32), ind: u32) u32 {
    return list.items[ind];
}


pub fn main() !u8 {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    const allocator = arena.allocator();

    var ar = ArrayList(u32).init(allocator);
    ar.ensureTotalCapacity(10) catch unreachable;
    ar.appendNTimes(0, 10) catch unreachable;
    const itemsAddress = &ar.items;
    const itemAddress = &ar.items[5];
    const throughFunc: *const u32 = &getFromList(&ar, 5);

    std.debug.print("{}, {}, {}", .{ itemsAddress, itemAddress, throughFunc });
    return 0;
}

I get the following output:
[]u32@16fd9ef98, u32@1001ac02c, u32@16fd9efec

Which I find strange, as it seems like the return through the function returns the actual memory location while taking the address of the items dereference doesn't? Also, why does the type of throughFunc here have to be *const u32 instead of *u32? I'd appreciate any help and pointers to documentation sections, thanks!

shrewd anchor
#

ar.items is a slice, meaning a pointer+length pair. &ar.times tells you where that pointer and length are stored, which in this case is the stack frame of main()

&ar.items[5] tells you where that integer is actually stored -- i.e. it does follow the pointer that's been allocated for the arraylist

&getFromList(&ar, 5) stores a temporary integer on the stack, and then gives you its address, which is why it has a similar address to &ar.items: they're both stored in main()'s stack

#

if you want the pointer where the array list contents are you can use ar.items.ptr

#

throughFunc has to be const because temporary values can't be modified in zig

strong yarrow
#

Oh ok this makes sense, thanks. So in general if I have a struct that stores data like ArrayLists, and say I have a .get(index,...) function to get values, and I want to sometimes get the values' address, the zig way would be to write a .getAddress(index,...) function rather than taking the address of .get()?

shrewd anchor
#

yes

#

cuz get() doesn't control where in memory its return value is stored; that is up to the caller

strong yarrow
#

Right, I guess C++ references corrupted my mind lol

#

Thx