Zig Notes

zig oddities
Login

zig oddities

Non-obvious ways where Zig is just different.

  1. lvalue semantics reach through control flow
  2. zig has supports integers of unusual width

lvalue semantics reach through control flow

discord link

const std = @import("std");

test "address of an optional's payload" {
    var n: ?u8 = 1;
    const p1: *u8 = &(n orelse return error.Unexpected);
    p1.* = 3;
    try std.testing.expectEqual(3, n.?);

    // same thing
    const p2 = if (n) |*p| p else return error.Unexpected;
    try std.testing.expectEqual(p1, p2);

    // p1 and p2 don't necessarily have the same address as &n .
    // That depends on how optionals are laid out in memory.

    var m: u8 = 2;
    n = null;
    const p3: *u8 = &(n orelse m);
    p3.* += 2;
    try std.testing.expectEqual(m, 4);

    var o: ?u8 = 3;
    const p4: *u8 = &(n orelse o.?);
    p4.* += 2;
    try std.testing.expectEqual(o, 5);
}

test "address of switch" {
    var a: u8 = 0;
    var b: u8 = 0;
    var c: u8 = 0;
    for (0..3) |i| {
        const p = &switch (i) {
            0 => a,
            1 => b,
            else => c,
        };
        p.* = @intCast(i + 1);
    }
    try std.testing.expectEqual(.{ 1, 2, 3 }, .{ a, b, c });
}

test "write to 'evil' after its lifetime" {
    var p: *usize = undefined;
    (blk: {
        var evil: usize = undefined;
        p = &evil;
        break :blk evil;
    }) = 5;
    try std.testing.expectEqual(5, p.*);
}

zig has supports integers of unusual width

const std = @import("std");

test "random integer widths" {
    const n1: u3 = 7;
    const n2: u100 = @bitCast(@as(i100, -1));
    var n3: u10 = 0;
    n3 -%= 1;
    const n4: i50 = std.math.maxInt(i33);
    const n5: i50 = std.math.maxInt(u33);
    const n6 = @as(u1000, std.math.maxInt(u500)) - n5;
    const n7: u0 = std.math.maxInt(u0);

    std.debug.print(
        \\n1 {}: {x}
        \\n2 {}: {x}
        \\n3 {s}: {}
        \\n4 {}: {x}
        \\n5 {}: {x}
        \\n6 {}: {}
        \\n7 {}: {}
        \\
    , .{
        @TypeOf(n1), n1,
        @TypeOf(n2), n2,
        "i10",       @as(i10, @bitCast(n3)),
        @TypeOf(n4), n4,
        @TypeOf(n5), n5,
        @TypeOf(n6), n6,
        @TypeOf(n7), n7,
    });
}