Welcome to my little blog! Feel free to reach out to me @cryptocode on Discord or Libera IRC

Zig asserts are not C asserts

I recently came across a piece of code in a Ziggit.dev post that gave me pause: pub fn putOne(q: *@This(), io: Io, item: Elem) Cancelable!void { assert(try q.put(io, &.{item}, 1) == 1); } pub fn getOne(q: *@This(), io: Io) Cancelable!Elem { var buf: [1]Elem = undefined; assert(try q.get(io, &buf, 1) == 1); return buf[0]; } …which led me to ask the following: Just a quick side quest: Doesn’t the assert here risk put and get calls being optimized away?...

July 22, 2025

Embedding machine code in Zig

Linux and macOS Rosetta notes Assembling Calling from Zig A larger example with fast memcpy and syscalls Using assembly code with Zig is usually done via inline assembly, or by linking to object files produced by assemblers. This post explores a third way: write the assembly in a separate source file, run an assembler, and then embed the resulting machine code using @embedFile Linux and macOS Rosetta notes The code is tested on macOS, but also works with minor modifications on Linux (primarily the syscall number)...

July 29, 2023

Cache Me If You Can

How come making a struct in Zig less densely packed can give a huge performance increase, with far less variability? This post takes a look at false sharing and how it can be caused by packed data layouts and unintended field reorderings. While packing data closely together can be beneficial due to cache locality, false sharing must be taken into account when designing optimal data layouts for multithreaded programs. False sharing occurs when the data layout is at odds with the memory access pattern, namely threads updating thread-specific data that happens to fall on the same cache line....

July 9, 2023

Async CPU bound workers in Zig

Zig has async/await support, which is typically used for IO bound operations. In this article, however, we’ll use async/await to simplify writing a simple concurrent worker. Goal: use all the cores on the machine to find a randomly selected 64-bit number whose lower N bits are all cleared. How it works Instead of manually spinning up threads, we’re just going to use async/await, along with pub const io_mode = .evented; which informs the standard library to use a non-blocking event loop....

May 2, 2021

Bio - All your parentheses are belong to us

In a previous Zig post, we wrote a small postfix notation calculator. This post takes a look at something that take prefix notation to the extreme: a new language in the Lisp family called Bio The goal of this project is to make it easy to play around with Lisp dialect ideas and to make a well-documented and readable Lisp interpreter for others to learn from. This article aims to point out some key areas people stumble on when writing a basic Lisp interpreter....

April 25, 2021

Some notes on using Zig with Valgrind

Zig has a very nice built-in memory leak detector in its General Purpose Allocator (GPA), but sometimes you have to break out Valgrind to get to the bottom of things. When I first did this, I ran into a couple of problems, which I’m jotting down here along with solutions. Thanks to mikdusan, ifreund and lemonboy for helping me figure out various issues First of all, to get Valgrind going with Zig programs, you’ll have to switch to the C allocator....

April 25, 2021

Zig scripts?!?

Look at this beauty: //usr/bin/env zig run "$0" -- "$@" ; exit const std = @import("std"); pub fn main() !void { std.log.info("Awesome, it works\n", .{}); } Let’s make it executable and run it: chmod +x myscript.zig ./myscript.zig info: Awesome, it works This works because // is a comment in Zig, and just an empty path component as far as the shell is concerned Thanks to squirl for making the argument passing syntax more robus

April 24, 2021

A surprisingly capable RPN calculator in about 100 lines of Zig code

Summary: Reverse polish notation is awesome Zig is awesome Before solving quadratic equations and diving into code, let’s see if 2 + 2 is still 4: 2 2 + M0 = 4 Phew! Notice how every answer is placed in the next available memory slot. This will be useful in our next example where we calculate the two solutions to a quadratic equation: First we input the known values so these get memory slots we can reference, rather than repeating the constants....

March 1, 2021

Running Zig binaries on a KaiOS device

The goal here is to: Cross-compile a Zig program Root a KaiOS device, and then install and run the cross-compiled program on the device We’re not making a GUI app or anything here, just a small “Hello world” program that we’ll cross-compile and run on the device. All sorts of interesting things can be done from this point on. I’m using Android’s adb to push files to the device and to get a shell, so you’ll have to install that first if you wanna follow along....

January 27, 2021