How to force runtime evaluation?

For exploratory purposes, I want to write some code, and make sure it isn’t evaluated at compile time. What’s the best way to achieve that? Right now, I am trying

pub fn main() { f(92) }
noinline fn f(arg: i32) void {}

where I think arg will be a runtime value.

Does this work? Is there a better way to do it?

1 Like

I’m not 100% sure, but I think that if the arg is a var, it can’t be evaluated at compile time. So

var n: i32 = 92;
f(n);

should do the trick? I arrive at this conclusion given that if you try to use a var i instead of a comptime var i with an inline while you get an error stating the i can’t be evaluated at compile time.

1 Like

Have you seen this thread? There was an @isComptime built in proposed a while ago: Add `@inComptime` builtin · mlugg/zig@35d82d3 · GitHub

I’m reading through the history of it right now and if I find out what happened to it I’ll post more here.

Here you can see something actually went in on this a while ago: Add `@inComptime` builtin · mlugg/zig@35d82d3 · GitHub

1 Like

Yeah, so this works for me - maybe it’ll help you? zig version 0.11.0-dev.3867+ff37ccd29

fn foo() void {
    if (@inComptime()) {
        @compileError("Woops");
    }
}

pub fn main() !void 
{
    // no-compile error:
    foo();


    // compile error:
    comptime foo(); 
    
}

The rule right now is that a function is called at comptime implicitly only when you’re already in a comptime context, otherwise it will need to be prefixed with comptime. There has been discussion about eventually have the compiler “try” to resolve function calls at comptime without explicitly asking for it, but none of that exists today.

So a function call in the top scope of a file is always comptime, while a function call inside main is always at runtime unless prefixed with comptime.

Not sure how that interacts with LLVM optimizations though, so you might get a non-comptime compile time resolution by LLVM when the function is simple enough.

3 Likes

Thanks for the links, there seems to be a warning

This can be used to provide alternative, comptime-friendly implementations of functions. It should not be used, for instance, to exclude certain functions from being evaluated at comptime.

Yes, and thank you for pointing out that those do have warnings attached to them (probably should have added that). @matklad seems like the kind of programmer that will dig into implementations to find out what the rules are, but for the general case it’s good to follow the warnings.

1 Like

Hi, just thought I’d quickly note: that note in @inComptime’s documentation isn’t any kind of technical restriction, it’s more of a recommendation. One of the main concerns with implementing that builtin was that people would start needlessly (and potentially wrongly) writing things like this:

if (@inComptime()) @compileError("This function must be run at runtime");

I chose to add this note simply to make it clear that this isn’t recommended. There’s no weird behavior here; the builtin does indeed just return whether it was evaluated in a comptime scope or not.

3 Likes