Articles on C

Last updated: 2023/03/24

Top deep-dives on C

Stop checking for NULL pointers!

When working with a lower level language like C, it is easy to cause problems that might make your whole program or system crash. So intuitively, you'd think we'd want checks to make sure these problems don't occur in the code we right. However,  in this article, Elad Lahav discusses how checking for one of such cases is actually detrimental in that it might lead to a false sense of security.

Build Your Own Text Editor

"This booklet walks you through building the editor in 184 steps" in C.

Defensive Programming - Friend or Foe?

Bugs are the bane of most software. It's especially bad when they cause the software to go into some unexpected or undefined state. In this article, Tyler Hoffman describes a more proactive and aggressive approach to catching and reporting bugs in embedded systems, compared to merely making sure bugs don't cause complete crashes.

malloc as a service

Linear Algebra Shenanigans: Gizmo Repair

Spotting problems and debugging them is as important in programming (if not more) as is writing the code in the first place. Obviously it would be better to not write buggy code in the first place, but sometimes that's out of your control. Fortunately Karl Zylinski has written an article about spotting an issue, narrowing down the problem space, adding visuals to help debug, and the ultimate solution, all for a game engine written in C.

Making Mass Effect not require administrator rights, or maybe how to not write a boolean check

Unfortunately I never got into modding video games (I wish I had, would've been fun), but that doesn't make me appreciate any less what what those devs do. Especially when you see some of the stuff they have to root around in. In this lengthy article, the author takes us along on a quest to discover the source of a register value issue triggering an unwanted action in a PC port of Mass Effect.

Making our own ping

But Alex, this is from almost a year ago! And it doesn't even link to a specific article! Blah reader! It might be... matured, and yes, there isn't a specific article at the link, there are 14! That's right, Amos has written a 14 part series on building your own ping, which starts from a short history of computer networking and culminates in crafting ICMP-bearing IPv4 packets with the help of bitvec. Looking as this essentially covered my entire class on networking in college, I figured it was worth sharing.

Writing a "bare metal" operating system for Raspberry Pi 4

Have you ever wanted to build an OS from scratch? No? Well that doesn't matter, because you can just read this series of interactive articles by Adam Greenwood-Byrne. Although shrouded in the guise of a tutorial, it's by no means a how-to, and Adam covers everything from bootstrapping to WordUp Graphics, all the while littering gems of knowledge along the way.

Writing a simple 16 bit VM in less than 125 lines of C

Title really says it all. Andrei Ciobanu starts with the basics of what a virtual machine is covers every step in the journey of implementing one.

Programming Style Influences

Not really a deep-dive, but I think it covers a subject that isn't much covered in programming. Laurence Tratt discusses how OpenBSD influenced his coding style and what people who write code have to gain from seeking out such influences.

Fun with Concepts: Do You Even Lift, Bool?

Concepts are a new feature in C++20 that we've had a few articles about in the past in this newsletter. In this article, the author demonstrates how they can be used to create better types than the ones offered by default in C++, and suggests that they make "constraining overloads and specializations" easier than ever before.


0xAX and some other contributors have made an online book on the Linux kernel and its inner workings. It's too long for me to add any highlights of use.

Implementing Hash Tables in C

Really, the title says it all. Is this extensive article by Andrei Ciobanu something your college professor would recommend? Probably. Does that make it any worse? Not really. Andre briefly covers hash functions, then begins taking apart the implementation of the hash table, starting with separate chaining. The article is still in draft form, but has good info, and gives you an opportunity to make comments on improvements/additions!

Let's write a compiler, part 1: Introduction, selecting a language, and doing some planning

Want to write your own compiler? Well I bet Brian Robert Callahan's seroes can help. In this first part, Brian sets out the specifications for what the compiler is going to be able to do, what language to implement it in, and lays out a couple of diagrams for the overall process flow for the compiler.

Program in Arm6 assembly language on a Raspberry Pi

"Assembly language is the symbolic language immediately above machine code and thereby offers special insights into how machines work and how they can be programmed efficiently". You also need to be a very special kind of person to want to program in it. If you are, Marty Kalin has written an article on load-store machines, writing the hstone program in C, assembly language basics, writing the hstone program again but in Arm6 assembly, and basically getting it all to run.

Chain loading, not preloading: the dynamic linker as a virtualization vector

Executable and Linkable Format (ELF), is a common standard file format for executable files, object code, shared libraries, and core dumps. In this technical article, Dr Stephen Kell shows how to "run a pre-existing binary program but in some kind of instrumented or modified form" using "ELF-level trickery", which essentially means writing a dynamic linker rather than using LD_PRELOAD.

A Bonding Exercise

The Linux bonding driver provides a method for aggregating multiple network interfaces into a single logical "bonded" interface. Patrik Lundin and his colleague were experimenting with one of these bonded interfaces when they noticed that the MAC address of the interface would change on network restart. This article details their quest for determining the cause.

Untangling Lifetimes: The Arena Allocator

Ryan Fleury illuminates his dislike of how it's the norm for everyone to be taught to stay away from manual memory management in C. Ryan argues that this way of thinking is nonsensical and that it's not necessary to introduce "automatic reference counting, RAII, and/or garbage collectors" as alternatives when there are simpler solutions, like the arena allocator.
Some highlights:

  • Malloc and free should rarely become the defacto memory management interfaces for a codebase
  • Memory leaks are "erased" when the program that created them errors or crashes
  • No easy way to mass free all mallocs relating to something
  • The general gist of the arena allocator is to use independent stacks to bucket memory allocations together

Finding Number Related Memory Corruption Vulns

"The root cause of many vulnerabilities are from the mishandling of numbers". Understandably so; how many of you actively think about the vulnerabilities of your code as you write it (excluding the high level topics like user sessions, etc)? Maxwell Dulin's article explores the different issues that might arise from using numbers in C, how you can spot them before they become truly costly.

The wild west of Windows command line parsing

Chris Wellons illuminates the weirdness (read outdatedness) of the Windows runtime's command line argument passing.

My Own Private Binary

How far would you go to make the smallest executable possible? Would you write your own kernel module? No? Well that's what Brian Raiter did, and now has written an article about it. In it, Brian demonstrates all of the necessary steps to get your kernel accepting a nonstandard Linux binary format.

C Structure Padding Initialization

Noah Pendleton dives into C structure padding, explaining what it is, the current state of it, best practices, and the future.

[OpenGL and Vulkan Interoperability on Linux] Part 2: Using OpenGL to draw on Vulkan textures.

As someone who has installed Arch Linux on two laptops that had two GPUs and did a deep dive over several months into machine learning on the GPU, I'm pretty familiar with the big GPU libraries. But I'll be the first to admit that my knowledge is limited to only a higher-level understanding. Fortunately, there are 10 part series like this one by Eleni Maria Stea that get down and dirty in the details of OpenGL and Vulkan. In this part of the series, Eleni demonstrates how "Vulkan/GL interoperability" can be achieved "where an image is allocated using Vulkan and filled using OpenGL".

Working with Strings in Embedded C++

Niall Cooling covers ALL things strings for deeply "embedded/bare-metal systems".

Page Fault Injection in Virtual Machines: Accessing Swapped-Out Pages from HVMI

Andrei Lutas discusses how page fault injection allows Hyper Memory Introspection to analyze normally unreachable guest memory that has been swapped-out of physical memory.

Making Sense of Acquire-Release Semantics

Dave Kilian discusses acquire-release semantics and how they are applied to writing lock-free code in native languages like C, C++ and Rust.
Some highlights:

  • "If memory worked the way you thought it did, you’d never need to acquire or release anything. Unfortunately, memory doesn’t work the way you think it does"
  • Code examples in C
  • CPU optimizations make memory nonlinearizable

That is not a number, that is a freed object

Siddhesh Poyarekar explains how a common approach to pointer reallocation incorrectly breaks function fortification.

Fast CSV processing with SIMD

If you’re working with csv data using standard UNIX tools like awk, sed, sort, etc. then you might run into issues with embedded commas and newlines being incorrectly interpreted as separators. In this concise article, Chris Wellons demonstrates his own optimized implementation of a library that helps you handle these issues and explains how he went about optimizing it.

Pointers Are Complicated III, or: Pointer-integer casts exposed

Ralf Jung demonstrates how compiler optimizations related to pointer to integer casting can result in unwanted behavior.

Racing the Hardware: 8-bit Division

Nima Badizadegan shows how division on the CPU can be accelerated using software to almost match hardware acceleration components.

ARM Cortex-M33 Instruction Tracing Without a Debugger

Debugging processors can be a pain, because more of than not, you'll need additional hardware just to get the debugging info from the processor. But that's not always the case. In this article, Chris Coleman demonstrates how a Micro Trace Buffer driver can be written for some modern ARM processors, allowing you to capture and analyze debug dumps with a Python script.

My take on "where's all the code"

Chris Wellons discusses some of the design choices and interesting aspects of implementing his own program in C that counts the lines of code in each part of a source tree.

A flexible, lightweight, spin-lock barrier

Chris Wellons explains how he developed the titular feature while trying out a memory reordering experiment in C11 and Go.

A System-Witch's Package Manager Murder Mystery

Artemis Everfree walks us through fixing an obscure bug related to exported env vars when running a package manager on a Linux machine.

Porting Doom to Helios

Drew DeVault ports DOOM to the Helios microkernel.

What's the Most Portable Way to Include Binary Blobs in an Executable?

Laurence Tratt elaborates on the nuances of having blobs in cross platform executables.

Linux in a Pixel Shader - A RISC-V Emulator for VRChat

This has been around for a bit, but thought it was still worth putting in here. You ever wanted to run Linux in VR chat? Like have it running right there in front of your eyes in your GPU? No? We'll you're clearly not a dreamer like Stefan. In this informative article, Stefan goes through the ins and outs of what it took to get CPU emulator with Linux running in VR chat.

All about sanitizer interceptors

MeowRay discusses how sanitizers work and the requirements of sanitizer interceptors.
Some highlights:

  • Interceptors work differently on ELF, Apple, and Windows platforms
  • Interceptors have a number of requirements for each platform
  • Sanitizers leverage symbol interposition to redirect such library function calls to their own implementation: interceptors

Saving Memory Subsystem Bandwidth

Ivica Bogosavljević discusses ways to make software run more efficiently, with a focus on using less memory resources.
Some highlights:

  • The goal is to make programs that are "frugal" in their use of resources, in contrast to programs that are focused on speed
  • There are two ways to make programs more frugal: CPU policies and modifying the program
  • Ivica explores both

Dusting off Dreamcast Linux

This article is about a version of Linux that was created for the Dreamcast gaming console. It was one of the earliest versions of Linux for game consoles, and it is still possible to run it on a Dreamcast today.
Some highlights:

  • Discusses some of the unique features of this version of Linux, and provides instructions on how to set it up
  • The author attempts some of the old kernel libraries, while trying not to break the whole system
  • Presents some of the history of the OS

GDBWave - A Post-Simulation Waveform-Based RISC-V GDB Debugging Server

Tom Verbeure goes on a deep-dive hooking up a GDB server with a RISC-V CPU to make debugging FPGAs easier.

Printing real headline news on the Commodore 64 with The Newsroom's Wire Service

The article discusses the ClassicHasClass's experience editing periodicals and how technology has changed since they first started. They discuss how they used Springboard Software's The Newsroom to edit their first periodical and how they used QuarkXPress for their most recent project. They also talk about how they used an Apple II to edit their high school newspaper and how the process has changed since then.
Some highlights:

  • Dives into file storage and contents on the Commodore 64
  • Goes into handling images and modern news articles
  • End result is a printed page of a modern news article

Why Rust mutexes look like they do

Cliff L. Biffle compares Rust mutex API design to C, and explains why the latter is fundamentally inline with core Rust principles.

Patching an Embedded OS from 1996 with Ghidra

Peter Sobot reverse engineers the OS for an old synthesizer to make it "do all sorts of other things".

goto hell;

Christopher Bazley argues that the use of goto statements in C programming is not as effective as other methods of error handling, despite being a widely used practice. Christopher cites several examples of why this is the case and argues that programmers should be more open to other methods of error handling.
Some highlights:

  • goto should only really be used to abandon processing in some deeply nested structure, such as breaking out of two or more loops at once
  • Deferred error handling > Error handling by early exit from a function

Want to see more in-depth content?

subscribe to my newsletter!

Other Articles