-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Edit: Original title was "Add compiler error for comptime pointer parameter with side-effects". The correct behavior is described in this comment.
const warn = @import("std").debug.warn;
fn inc(comptime foo: *usize) void {
foo.* += 1;
}
pub fn main() void {
comptime var bar: usize = 0;
inc(&bar);
warn("{}\n", bar);
}
This outputs 0
which is unexpected behavior to me. I would have expected the inc
call would implicitly be called at compile-time.
Explicitly calling the function at comptime resolves this. This isn't a suitable workaround for me unfortunately since I'm actually passing varargs as well which do not work at comptime.
const warn = @import("std").debug.warn;
fn inc(comptime foo: *usize) void {
foo.* += 1;
}
pub fn main() void {
comptime var bar: usize = 0;
comptime inc(&bar);
warn("{}\n", bar);
}
I presume the compiler doesn't see that inc
has side-effects for its input, and the runtime call simply becomes an empty function after it is resolved. Thinking a bit more, I think the existing behavior is correct, and it is more the lack of a compiler error which is the issue.
A workaround is to avoid comptime pointer parameters and return the values as needed. This correctly catches the issue with a compiler error.
const warn = @import("std").debug.warn;
fn inc(comptime foo: usize) usize {
return foo + 1;
}
pub fn main() void {
comptime var bar: usize = 0;
bar = inc(bar);
warn("{}\n", bar);
}
$ zig run t.zig
/tmp/t.zig:9:9: error: cannot store runtime value in compile time variable
bar = inc(bar);
^
May be fundamentally the same as #906.