my prelude.h for C coding

customize your environment to bring joy to programming

I’ve recently started using a prelude.h include file to customize how my C projects look and feel. If you’ve read the last couple of posts featuring C code you’ve probably noticed the types look a bit… Rusty. A long time ago I did an experiment, writing a text editor in a very dense obfuscated style. It was a mess, and I did end up reverting to a more normal style. One thing I did really like was having more concise standard types. In that project int was i, char was c, etc. That’s too much. I’ve settled on nice Rust-style types. I include typedefs for those, a bunch of include boilerplate I use in almost every project, and a growing collection of utility functions into one header file and started using it everywhere.

easy project setup

I’ve written before about unity builds as a way to make setting up a project easier. The prelude.h extends that simple setup to my includes. It’s a small thing, but it’s nice not having to keep a big include list up to date. If it’s some boilerplate I’m almost always using, just throw it in prelude.h.

It’s also a great home for small utility functions and macros. I have a sequal function that does strcmp() == 0. I have a swap, and an ease. All tiny things that are just nice to have everywhere. I’m sure I’ll end up with pick and slurp at some point, but I haven’t added them yet.

typedef int bool;
#define true 1
#define false 0

// Simple assert macro; prints to stderr and then aborts.
#define assert(c, msg) do { if (!(c)) { fprintf(stderr, "%s\n", msg); abort(); }} while(false)

typedef uint8_t   u8;
typedef int32_t   i32;
typedef uint32_t  u32;
typedef uint64_t  u64;
typedef float     f32;
typedef double    f64;
typedef char      byte;
typedef ptrdiff_t size;
typedef size_t    usize;
typedef char*     str;

static f32 ease(f32 current, f32 target, f32 speed, f32 dt)
{
    return current + (target - current) * (1 - exp(-speed * dt));
}

It’s nice to build up a list of utilities that work the way I want them to, and that I can hack up easily.1 I love hopping around to different programming languages all the time but I feel like one of the big downsides of that is that I don’t have my own set of utilities that get copied into every project. Now that I’m starting to consciously work on that for my C projects I wish I had done it sooner!

small editor customizations are neat too

Another little trick I did was customize my C syntax highlighting in vim. To force myself to use the new types, I added syntax highlighting that underlines them in red. I’d keep typing int32_t and such out of habit, but now the syntax highlighter yells at me. All of my new typedefs get highlighted like they’re builtins.

Lately I have been trying to avoid using unsigned ints as much as possible. Sometimes you need to use them, but in C comparing signed and unsigned integers is fraught with peril. I’ve had way too many infinite loops turn out to be due to bad signed vs unsigned comparisons, and one of the nastiest bugs I’ve seen in production was caused by it. So now I try to just avoid unsigned where I can. I made the syntax highlighter show unsigned types with a yellow underline. It really draws attention to them and makes me double check to ensure they’re really needed. I think in all of the C I’ve written this year I’ve only really needed u32 for my xorshift RNG.

" .vim/after/syntax/c.vim
" custom typedefs from prelude.h
syntax keyword cType u8 i32 u32 u64 f32 f64 byte size usize str

" old types that are overridden by prelude types
syntax keyword cOldType int double float size_t ptrdiff_t
syntax keyword cOldType uint8_t uint32_t uint64_t int32_t
syntax keyword cOldType long short unsigned signed
highlight cOldType ctermfg=Red cterm=underline guifg=Red gui=underline

" yellow underline for unsigned typedefs
syntax keyword cUnsignedType u8 u32 u64 usize
highlight cUnsignedType ctermfg=Yellow cterm=underline guifg=Yellow gui=underline

For side projects you really can’t beat customizing stuff. I’m starting to think for larger projects and for corporate work it’s making more and more sense to have a mostly in-house standard library as well. There was recently a supply chain attack in the Rust ecosystem, targeting the arrayref crate. I think the macros in question are a great candidate for dropping into a prelude.h type of library within your project / company instead of bringing in a dependency. And I think it’s the kind of dependency crate authors need to avoid to help keep transitive dependencies clean.

As a younger engineer I learned in an environment where avoiding “Not Invented Here” syndrome was considered very important. Don’t reinvent the wheel, library authors will catch way more bugs and you’ll benefit from their fixes. But over the years I think supply chain risk has undermined that quite a bit, and a lot of very highly touted libraries turn out to be not so great if you start reading the code.

And sometimes making wheels is fun.


  1. For example, right now I’m using my own bool typedef. I’m not super attached to that though, I can easily swap it out later if it causes problems.↩︎

Changelog

Sep 1 2026 — published initial version