The VikiD Truth

Knowledge base / Computing / C & systems languages

Read This! | | Quick Links | Algorithms | AssemblyLanguage | BASH | C-Programmming | CommonLisp | Computer Security | Databases | Emacs | Exploitation | Functional Programming | Firewalls | Git | Haskell | Javascript | Julia | Social Engineering | Picolisp | Pharo Smalltalk | Purescript | Linux | Python | Operating Systems | Machine Learning | Metasploit | Open Data Science | Networking | Machine Learning | Racket | Scheme | Unity | vim | V | Web Development | Windows WSL | Zig

Zig Language

Here is the truth Zig is aimed at: C is still the lingua franca of systems, but its undefined behaviour, header files and build story are a tax everyone pays. Zig keeps C’s honesty about memory and lays that tax down.

What it is, in plain words

Zig is a general-purpose systems language created by Andrew Kelley, first appearing around 2016, still pre-1.0 (the 0.13/0.14 line in 2025–2026) but already used in real tools – including the ncdu 2 rewrite and parts of Bun’s toolchain. Its pitch:

Zig can compile C code, import C headers directly with @cImport, and link against C libraries with almost no glue – which makes it a practical “better C” migration path.

Why it matters

If you write anything close to the metal – kernels, embedded, game engines, CLI tools, language runtimes – C and C++ still dominate, and their footguns still cause CVEs. Zig is one of the serious attempts (alongside Rust and Odin) to keep the control and drop the undefined behaviour. Even if you never ship Zig, its compiler as a portable C toolchain is already useful.

An everyday analogy: a transparent gearbox

C is a classic sports car: fast, direct, and if you miss a shift you blow the engine (undefined behaviour). Rust adds a gearbox with a lockout that won’t let you miss a shift (the borrow checker). Zig keeps the manual gearbox but puts a clear cover on it and labels every cable – you still shift yourself, but you see every linkage and nothing moves unless you move it.

flowchart LR
  Z[".zig source"] --> C[zig build]
  C --> N[native binary]
  C -.->|cross| X["linux-aarch64 / windows / wasm"]
  C -.->|zig cc| CC[compile C/C++ too]

A hands-on example

Install from the official tarball (distro packages often lag; Zig moves fast):

# example: unpack a release and put it on PATH
curl -L https://ziglang.org/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz | tar -xJ
export PATH="$PWD/zig-linux-x86_64-0.13.0:$PATH"
zig version
// hello.zig
const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    try stdout.print("hello from {s}\n", .{"vikix"});

    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var list = std.ArrayList(i32).init(allocator);
    defer list.deinit();
    try list.append(3);
    try list.append(1);
    try list.append(4);

    // comptime: this loop runs at compile time
    const squares = comptime blk: {
        var arr: [5]i32 = undefined;
        for (&arr, 0..) |*slot, i| slot.* = @intCast(i * i);
        break :blk arr;
    };
    try stdout.print("squares: {any}\n", .{squares});
    try stdout.print("list: {any}\n", .{list.items});
}
zig run hello.zig
zig build-exe hello.zig -O ReleaseFast

A tiny build.zig for a real project:

const std = @import("std");
pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});
    const exe = b.addExecutable(.{
        .name = "hello",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });
    b.installArtifact(exe);
}
zig build
zig build -Dtarget=aarch64-linux-gnu   # cross-compile, no extra toolchain

That last line is a Zig party trick: the same compiler produces binaries for other platforms without you installing a cross-GCC.

Zig, C and Rust

CZigRust
Memorymanualmanual, explicit allocatorsownership, borrow checker
Safetyuncheckedbounds checks in safe modes; unreachable is loudprevents most memory bugs at compile time
Buildmake/cmakebuilt inCargo
C interop–best-in-classgood via bindgen
Errorsreturn codeserror sets, tryResult, ?

Common misconceptions

Connections

Last edited · 1 revisions

Tags: #Computing