Blogs / Personal blogs

Chris Wellons

nullprogram.com

Buffered output typically comes in two flavors: fully buffered and line buffered. If output goes to a terminal then the implementation automatically selects line buffering, flushing its buffer when a line is completed so that it reaches the user immediately. Otherwise it fully buffers, holding output until the buffer…

Popular posts
74
Total points
14,949
HN comments
7,192
Rank
#45 personal

Visit nullprogram.com → RSS feedOn Hacker News Dec 2014 – Oct 2026

Software Engineering 64Systems & Performance 21Programming Languages 17Tools & Productivity 15Math & Algorithms 8Security & Privacy 7

2

My personal C coding style as of late 2023

This has been a ground-breaking year for my C skills, and paradigm shifts in my technique has provoked me to reconsider my habits and coding style. It’s been my largest personal style change in years, so I’ve decided to take a snapshot of its current state and my reasoning. These changes have produced significant…

3

Why Aren't There C Conferences?

Most widely-used programming languages have at least one regular conference dedicated to discussing it. Heck, even Lisp has one . It’s a place to talk about the latest developments of the language, recent and upcoming standards, and so on. However, C is a notable exception. Despite its role as the foundation of the…

4

Go's Tooling Is an Undervalued Technology

Regardless of your opinions of the Go programming language , the primary implementation of Go, gc, is an incredible piece of software engineering. Everyone ought to be blown away by it! Yet not only is it undervalued in general, even the Go community itself doesn’t fully appreciate it. It’s not perfect, but it has…

5

You might not need machine learning

Machine learning is a trendy topic, so naturally it’s often used for inappropriate purposes where a simpler, more efficient, and more reliable solution suffices. The other day I saw an illustrative and fun example of this: Neural Network Cars and Genetic Algorithms . The video demonstrates 2D cars driven by a neural…

6

Minimalist C Libraries

In the past year I’ve written a number of minimalist C libraries, particularly header libraries. The distinction for “minimalist” is, of course, completely arbitrary and subjective. My definition in this context isn’t about the library’s functionality being stupidly trivial or even necessarily simple. I’m talking…

7

Go Slices Are Fat Pointers

One of the frequent challenges in C is that pointers are nothing but a memory address. A callee who is passed a pointer doesn’t truly know anything other than the type of object being pointed at, which says some things about alignment and how that pointer can be used… maybe. If it’s a pointer to void ( void * ) then…

8

The Day I Fell in Love with Fuzzing

In 2007 I wrote a pair of modding tools, binitools , for a space trading and combat simulation game named Freelancer . The game stores its non-art assets in the format of “binary INI” files, or “BINI” files. The motivation for the binary format over traditional INI files was probably performance: it’s faster to load…

10

Infectious Executable Stacks

In software development there are many concepts that at first glance seem useful and sound, but, after considering the consequences of their implementation and use, are actually horrifying. Examples include thread cancellation , variable length arrays , and memory aliasing . GCC’s closure extension to C is another…

11

A Tutorial on Portable Makefiles

In my first decade writing Makefiles, I developed the bad habit of liberally using GNU Make’s extensions. I didn’t know the line between GNU Make and the portable features guaranteed by POSIX. Usually it didn’t matter much, but it would become an annoyance when building on non-Linux systems, such as on the various…

12

My favorite C compiler flags during development

The major compilers have an enormous number of knobs . Most are highly specialized, but others are generally useful even if uncommon. For warnings, the venerable -Wall -Wextra is a good start, but circumstances improve by tweaking this warning set. This article covers high-hitting development-time options in GCC…

13

A Branchless UTF-8 Decoder

This week I took a crack at writing a branchless UTF-8 decoder: a function that decodes a single UTF-8 code point from a byte stream without any if statements, loops, short-circuit operators, or other sorts of conditional jumps. You can find the source code here along with a test suite and benchmark:

14

Arena allocator tips and tricks

Over the past year I’ve refined my approach to arena allocation . With practice, it’s effective, simple, and fast; typically as easy to use as garbage collection but without the costs. Depending on need, an allocator can weigh just 7–25 lines of code — perfect when lacking a runtime . With the core details of my own…

15

I have officially retired from Emacs

This past Tuesday I typed C-x C-c in Emacs for the last time after 20 years of daily use. Though nearly half that time was gradually retiring it, switching to modal editing, then to Vim. Emacs is a platform, and I’d grown accustomed to its applications, especially those I built myself. There was no particular hurry…

18

When Parallel: Pull, Don't Push

I’ve noticed a small pattern across a few of my projects where I had vectorized and parallelized some code. The original algorithm had a “push” approach, the optimized version instead took a “pull” approach. In this article I’ll describe what I mean, though it’s mostly just so I can show off some pretty videos…

19

My ranking of every Shakespeare play

A few years ago I set out on a personal journey to study and watch a performance of each of Shakespeare’s 37 plays. I’ve reached my goal and, though it’s not a usual topic around here, I wanted to get my thoughts down while fresh. I absolutely loved some of these plays and performances, and so I’d like to highlight…

21

Let's write a setjmp

Yesterday I wrote that setjmp is handy and that it would be nice to have without linking the C standard library. It’s conceptually simple, after all. Today let’s explore some differently-portable implementation possibilities with distinct trade-offs. At the very least it should illuminate why setjmp sometimes requires…

22

The CPython Bytecode Compiler Is Dumb

Due to sheer coincidence of several unrelated tasks converging on Python at work, I recently needed to brush up on my Python skills. So far for me, Python has been little more than a fancy extension language for BeautifulSoup , though I also used it to participate in the recent tradition of writing one’s own static…

27

Raw Linux Threads via System Calls (2015)

Linux has an elegant and beautiful design when it comes to threads: threads are nothing more than processes that share a virtual address space and file descriptor table. Threads spawned by a process are additional child processes of the main “thread’s” parent process. They’re manipulated through the same process…

28

Quite OK Image is now my favorite asset format

The Quite OK Image (QOI) format was announced late last year and finalized into a specification a month later. Initially dismissive, a revisit has shifted my opinion to impressed. The format hits a sweet spot in the trade-off space between complexity, speed, and compression ratio. Also considering its alpha channel…

29

Rolling Shutter Simulation in C

The most recent Smarter Every Day (#172) explains a phenomenon that results from rolling shutter . You’ve likely seen this effect in some of your own digital photographs. When a CMOS digital camera captures a picture, it reads one row of the sensor at a time. If the subject of the picture is a fast-moving object…