Zig: @ptrToInt error: unable to evaluate constant expression

Created on 8 May 2020  路  2Comments  路  Source: ziglang/zig

With 0.6.0, @ptrToInt() surprisingly cannot be used as a constant expression:

Screen Shot 2020-05-08 at 06 56 12

The contents of the aforementioned function_table.zig minimal reproduction case:

const std = @import("std");
const testing = std.testing;

export fn my_func() void {}

const ExportedFunction = struct {
  name: []const u8,
  ptr: usize, // function types vary
};

const functions = [_]ExportedFunction {
  .{.name = "my_func", .ptr = @ptrToInt(&my_func)},
};

test "reproduce error: unable to evaluate constant expression" {
  testing.expect(functions[0].ptr != 0);
}

By the way, in case there's any better way to create a function lookup table storing function pointers (with varying function type signatures) to exported functions, I'm all ears...

Most helpful comment

The error is correct since the address of the function is not compile time known. If you want to make a function lookup table you have a few different choises:

  • use @ptrCast(fn()void, my_func) and then @ptrCast again when you want to call it.
  • put the look up table in a runtime scope like inside a function and use @ptrToInt.
  • use tuples:
const std = @import("std");
const testing = std.testing;

export fn my_func() void {}
export fn my_other_func() u32 {return 0;}

const functions = .{
    .my_func = my_func,
    .my_other_func = my_other_func,
};

test "reproduce error: unable to evaluate constant expression" {
    testing.expect(@ptrToInt(functions.my_func) != 0);
    testing.expect(@ptrToInt(functions.my_other_func) != 0);
}

All 2 comments

The error is correct since the address of the function is not compile time known. If you want to make a function lookup table you have a few different choises:

  • use @ptrCast(fn()void, my_func) and then @ptrCast again when you want to call it.
  • put the look up table in a runtime scope like inside a function and use @ptrToInt.
  • use tuples:
const std = @import("std");
const testing = std.testing;

export fn my_func() void {}
export fn my_other_func() u32 {return 0;}

const functions = .{
    .my_func = my_func,
    .my_other_func = my_other_func,
};

test "reproduce error: unable to evaluate constant expression" {
    testing.expect(@ptrToInt(functions.my_func) != 0);
    testing.expect(@ptrToInt(functions.my_other_func) != 0);
}

Kind thanks, @Vexu, that is most helpful. TIL. Closing the issue since it's not a bug.

Was this page helpful?
0 / 5 - 0 ratings