#strange error

1 messages · Page 1 of 1 (latest)

thorny haven
#
const std = @import("std");
const Allocator = std.mem.Allocator;

const Any = struct {
    ptr: *anyopaque,
    allocator: Allocator,
    OriginalType: type,

    const Self = @This();

    fn init(comptime T: type, allocator: Allocator, value: T) Allocator.Error!Self {
        const ptr = try allocator.create(T);
        ptr.* = value;

        return Self{
            .ptr = ptr,
            .allocator = allocator,
            .OriginalType = T,
        };
    }

    fn deinit(self: Self) void {
        const original_ptr: *self.OriginalType = @ptrCast(@alignCast(self.ptr));
        self.allocator.destroy(original_ptr);
    }

    fn asValue(self: Self) self.OriginalType {
        const original_ptr: *self.OriginalType = @ptrCast(@alignCast(self.ptr));
        return original_ptr.*;
    }
};

pub fn main() !void {
    const allocator = std.heap.page_allocator;
    var a1 = try Any.init(i32, allocator, 10);
    defer a1.deinit();

    std.debug.print("{d}", .{a1.asValue()});
}
#
run
└─ run hello_world
   └─ zig build-exe hello_world Debug native 1 errors
C:\dev\zig-windows-x86_64-0.14.0-dev.781+f03d54f06\lib\std\os\windows.zig:1758:33: error: comptime call of extern function
    return kernel32.VirtualAlloc(addr, size, alloc_type, flProtect) orelse {
        
C:\dev\zig-windows-x86_64-0.14.0-dev.781+f03d54f06\lib\std\heap\PageAllocator.zig:24:42: note: called from here
        const addr = windows.VirtualAlloc(
                     ~~~~~~~~~~~~~~~~~~~~^
C:\dev\zig-windows-x86_64-0.14.0-dev.781+f03d54f06\lib\std\mem\Allocator.zig:86:29: note: called from here
    return self.vtable.alloc(self.ptr, len, ptr_align, ret_addr);

C:\dev\zig-windows-x86_64-0.14.0-dev.781+f03d54f06\lib\std\mem\Allocator.zig:225:35: note: called from here
    const byte_ptr = self.rawAlloc(byte_count, log2a(alignment), return_address) orelse return Error.OutOfMemory;

C:\dev\zig-windows-x86_64-0.14.0-dev.781+f03d54f06\lib\std\mem\Allocator.zig:105:62: note: called from here
    const ptr: *T = @ptrCast(try self.allocBytesWithAlignment(@alignOf(T), @sizeOf(T), @returnAddress()));
                       
src\main.zig:12:41: note: called from here
        const ptr = try allocator.create(T);
                       
src\main.zig:35:26: note: called from here
    var a1 = try Any.init(i32, allocator, 10);
                 
referenced by:
    WinStartup: C:\dev\zig-windows-x86_64-0.14.0-dev.781+f03d54f06\lib\std\start.zig:580:37
    comptime_0: C:\dev\zig-windows-x86_64-0.14.0-dev.781+f03d54f06\lib\std\start.zig:65:21
#

can someone please explain this error?

wanton summit
#

ah that's why

#

the Any struct is comptime-only because it has a type field

thorny haven
#

error: comptime call of extern function
is this because init takes a value at comptime, so allocator.create fails?

#

oh ok

wanton summit
#

when a function returns a comptime-only value, the function is made comptime-only

#

that means init is comptime-only

thorny haven
#

i see

wanton summit
#

so calling allocator.create fails because you can't do that at comptime

thorny haven
#

so how can i preserve the original type at runtime? is that even possible?

wanton summit
#

no

#

you can allocate a byte slice with the correct size and and align(16) instead

#

and then store original_size: usize

#

and cast back to a byte slice to free it

#

.asValue would need to have the type passed in

thorny haven
#

hmm i see

#

why would it have to be a byte slice?

wanton summit
#

just so you can allocate it because it needs a length

#

you could make it so deinit needs the OriginalType too and then there's no need to do that

thorny haven
#

yeah ima just do that, more simple