I’m trying to figure out if the below is a bug (missed warning or error) or just a footgun related returning a pointer to a stack value.
I had this bug when coding day 17 for AoC 2024 and noticed that the outSlice() method was returning garbage. I think what’s happening is that the VM instance gets passed by value from main() into the outSlice() method, and then that method returns a pointer to a local VM copy’s out buffer.
This head scratcher got me thinking: why would I ever pass self as anything else than a pointer?
When you have an immutable structure and the size of the structure is small (up to the size of two registers). The reason is because you don’t need to allocate extra memory for the object.
outSlice returns a pointer to temporary memory. Since the out field is an array, it is copied when you pass VM by value. You return a pointer (slice) to this local copy which becomes invalid after the function returns.
Yeah, so the thing is I’ve managed to do the “return stack address” bug in Zig a bunch of times with relative ease, whereas this would be a rare occurrence if I was writing C. It’s probably because I’m more experienced in C and more vigilant because I know C is a glass cannon, but still… somehow I’m a bit blind to this class of bugs in Zig.
BTW, GCC issues a warning about this with default settings:
#include <stdio.h>
typedef struct {
char buf[256];
} Test;
static char* foo(Test a) {
return &a.buf[0];
}
int main() {
Test a;
char* p = foo(a);
}
→
gcc foo.c
foo.c: In function ‘foo’:
foo.c:10:12: warning: function returns address of local variable [-Wreturn-local-addr]
10 | return &a.buf[0];
| ^~~~~~~~~
I’d imagine this would be the type of thing Zig linting tools would be able to catch in the future. In my opinion, as a bug this is at least on the same level of severity as the current “const vs var” or “unused variable” errors Zig issues.
BTW I hope I don’t come across as a complainer. This particular type of bug just seems to come easy for me and I can’t quite point my finger what it is about the language that makes it easier than in C.