How do I use this allocator snippet from the 0.14.0 release notes for zig 0.15.1?

From here.

The snippet:

var debug_allocator: std.heap.DebugAllocator(.{}) = .init;

pub fn main() !void {
    const gpa, const is_debug = gpa: {
        if (native_os == .wasi) break :gpa .{ std.heap.wasm_allocator, false };
        break :gpa switch (builtin.mode) {
            .Debug, .ReleaseSafe => .{ debug_allocator.allocator(), true },
            .ReleaseFast, .ReleaseSmall => .{ std.heap.smp_allocator, false },
        };
    };
    defer if (is_debug) {
        _ = debug_allocator.deinit();
    };
}

For the life of me, I cannot find where native_os and builtin.mode are supposed to be defined.

I see in the docs there is a std.builtin but this doesn’t have .mode and OptimizeMode is like the types of them instead of just the names.

I see projects use builtins = @import("builtins") but this also doesn’t have .mode.

Likewise for native_os I cannot find anything in the docs for where this is supposed to come from.

If anyone could help me get this snippet running under zig 0.15.1 I would have much appreciation.

P.S.: if anyone knows how to get exact text searches on the site working, let me know. “native_os” in the search bar doesn’t get exact results.

const builtin = @import("builtin");

Not plural “builtins”, singular “builtin”.

native_os is not shown, likely builtin.os.tag. I have never targeted web assembly, so never bothered using that portion.

Note that @import("std").builtin is not the the same as @import("builtin").

Ah, thanks. Looks like I was using the singular in my source already.

Here’s the output:

run
└─ run exe jellytune
   └─ compile exe jellytune Debug native 1 errors
src/main.zig:9:39: error: root source file struct 'builtin' has no member named 'mode'
        break :gpa switch (std.builtin.mode) {
                           ~~~~~~~~~~~^~~~~
/home/gwendolyn/dev/Remote-Repos/github.com/ziglang/zig/build-0.15.1/stage3/lib/zig/std/builtin.zig:1:1: note: struct declared here
//! Types and values provided by the Zig language.
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

My source:

const builtin = @import("builtin");
const std = @import("std");

var debug_allocator: std.heap.DebugAllocator(.{}) = .init;

pub fn main() !void {
    const gpa, const is_debug = gpa: {
        break :gpa switch (std.builtin.mode) {
            .Debug, .ReleaseSafe => .{ debug_allocator.allocator(), true },
            .ReleaseFast, .ReleaseSmall => .{ std.heap.smp_allocator, false },
            else => unreachable,
        };
    };
    defer if (is_debug) {
        _ = debug_allocator.deinit();
    };
    _ = gpa;
}

Ah, yup I see the error.

I must have gotten mixed up between trying out std. and the pluralization and just missed this exact correct invocation.

Thank you this makes sense.

to clarify the difference:

@import("builtin") is a zig file that the compiler generates for each compilation, it provides a lot of meta data for the specific compilation.

std.builtin is file in the standard library, it contains mostly type definitions that are used by the compiler, such as Type used for type reflection and generation, StackTrace, AtomicOrder, OptimizeMode, etc.

2 Likes

Makes sense, thank you. Yes this has come together. And it’s quite logical having had it pointed out by y’all!

For reference the correct code without typos:

const builtin = @import("builtin");
const std = @import("std");

var debug_allocator: std.heap.DebugAllocator(.{}) = .init;

pub fn main() !void {
    const gpa, const is_debug = gpa: {
        if (builtin.os.tag == .wasi) break :gpa .{ std.heap.wasm_allocator, false };
        break :gpa switch (builtin.mode) {
            .Debug, .ReleaseSafe => .{ debug_allocator.allocator(), true },
            .ReleaseFast, .ReleaseSmall => .{ std.heap.smp_allocator, false },
        };
    };
    defer if (is_debug) {
        _ = debug_allocator.deinit();
    };
    _ = gpa;
}

This correctly uses the singular const builtin = @import("builtin"); as well as builtin.os.tag to check for wasi.

1 Like