Skip to content

Side effects of function analysis should be applied at the call site #2710

@tiehuis

Description

@tiehuis

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviorfrontendTokenization, parsing, AstGen, Sema, and Liveness.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions