How to create two mutually referencing pointers at compile time?

At runtime, we can create two mutually referencing pointers like this:


test "runtime" {
    var x: *const anyopaque = undefined;
    var y: *const anyopaque = undefined;

    x = @ptrCast(&y);
    y = @ptrCast(&x);

    try std.testing.expectEqual(@intFromPtr(x), @intFromPtr(&y));
    try std.testing.expectEqual(@intFromPtr(y), @intFromPtr(&x));
}

However, when I attempt to create them at compile time, the following error occurs:


test "comptime" {
    const x, const y = comptime blk: {
        var x: *const anyopaque = undefined;
        var y: *const anyopaque = undefined;
        x = @ptrCast(&y);
        y = @ptrCast(&x);
        break :blk .{ x, y };
    };
    try std.testing.expectEqual(@intFromPtr(x), @intFromPtr(&y));
    try std.testing.expectEqual(@intFromPtr(y), @intFromPtr(&x));
}
error: runtime value contains reference to comptime var
    try std.testing.expectEqual(@intFromPtr(x), @intFromPtr(&y));

How can this be achieved?

TIPS: The code above is minimized for testing purposes; my goal is conceptually equivalent to creating a doubly linked list at compile time.

AFAIK It does not make sense to take the adress of a variable at compile time: it does not live in memory. Maybe using an array of structs, and indices would solve your issues ? The cool thing is that you can even add objects to the array at compile time using ++, no need to worry about allocation failures.

That’s a separate matter; this thread is intended to discuss pointer referencing.

When I force a change to the constant value, new problems arise.

test "comptime2" {
    const x, const y = comptime blk: {
        const x: *const anyopaque = undefined;
        const y: *const anyopaque = undefined;
        const addr_x: *@TypeOf(x) = @constCast(&x);
        const addr_y: *@TypeOf(y) = @constCast(&y);
        addr_x.* = @ptrCast(addr_y);
        addr_y.* = @ptrCast(addr_x);
        break :blk .{ x, y };
    };
    try std.testing.expectEqual(@intFromPtr(x), @intFromPtr(&y));
    try std.testing.expectEqual(@intFromPtr(y), @intFromPtr(&x));
}
error: unable to evaluate comptime expression
        addr_x.* = @ptrCast(addr_y);
        ~~~~~~~~~^~~~~~~~~~~~~~~~~~