💾 Archived View for koyu.space › aartaka › public › making-c-prettier.gmi captured on 2024-06-16 at 12:15:50. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2024-05-26)
-=-=-=-=-=-=-
By Artyom Bologov
<figure>
"A village landscape with people butchering animals and otherwise engaging in harvest activities"
<figcaption>
Picking up fruit of good C programming. "Autumn" by Pieter van der Heyden, 1570
</figcaption>
</figure>
C has a bad rap for being unreadable.
I've already explored
so this is a sequel complementing the original post.
I'm going through the ways one can make their C code
more readable and modern-looking.
This time, I don't have a piece of code to experiment on.
Most of the examples are taken from Suckless software and redacted for readability.
So yes, this post is a bit of appreciation for the community work.
Now, to the exact prettiness hacks.
I know I listed indentation styles as ugly
But that's the whole point of indentation styles: making the code more readable.
Some styles look ugly but accomplish a certain goal nonetheless.
I'm using a Linux Kernel Style in my projects, because it looks good and promotes good practices.
But you can always call me out as wrong.
This one is pretty obvious: you can omit the curly braces marking block start/end.
In most control structures: if/else, for, do/while.
Suckless software utilizes that for increased readability and brevity.
void tdefutf8(char ascii) { if (ascii == 'G') term.mode |= MODE_UTF8; else if (ascii == '@') term.mode &= ~MODE_UTF8; }
Looks quite Pythonic to me. Do we need Python if we have this in C?
Missing true/false when dealing with boolean data?
Not sure how may bytes a certain value occupies?
Like how Rust did with <code>u32</code> and <code>i64</code>?
C99 headers—
for booleans,
for fixed width types—to the rescue!
typedef struct { Rune u; ushort mode; uint32_t fg; uint32_t bg; } Glyph;
There are more types in this snippet—ushort, Rune, Glyph.
But these are Suckless types.
Still, sane typedefs make your code more readable.
Well, if you're considerate enough.
Python and JavaScript have a readable literal object syntax:
{key1: value1, key2: value2} [elem1, elem2, elem3]
C has more primitive data structures,
but there are literal initializers that share some of this readability.
// Structure initializers: {value1, value2} {.key1 = value1, .key2 = value2} // Array initializers: {elem1, elem2, elem3} {[0] = elem1, [1] = elem2, [2] = elem3}
Here's initializer-based Surf config snippet (actually part of my setup)
that shows why Suckless software is so readable and configurable:
static Parameter defconfig[ParameterLast] = { /* parameter Arg value priority */ [AccessMicrophone] = { { .i = 0 }, }, [AccessWebcam] = { { .i = 0 }, }, [Certificate] = { { .i = 0 }, }, [CaretBrowsing] = { { .i = 1 }, }, [CookiePolicies] = { { .v = "@" }, }, [DarkMode] = { { .i = 1 }, }, [DefaultCharset] = { { .v = "UTF-8" }, }, [DiskCache] = { { .i = 1 }, }, [DNSPrefetch] = { { .i = 0 }, }, /* ... */ [MediaManualPlay] = { { .i = 1 }, }, [PreferredLanguages] = { { .v = (char *[]){ "en_US" } }, }, /* ... */ [WebGL] = { { .i = 0 }, }, [ZoomLevel] = { { .f = 1.3 }, }, };
There is also an option (since C11) to pass anonymous structures to functions, instead of allocating, passing, freeing the data just for one call.
Saves you a couple of lines and many use-after-free errors.
C is statically typed and you have to provide types for everything.
And it's overly verbose and uncomfortable to write programs in.
Right? There actually is generic dispatch in C11
#define print_val (val) _Generic((val), int: printf("%i\n", val), char*: puts(val))
And there is type inference starting from C23:
#define iter (times) for(typeof(times) i = 0; i < times; ++i)
That's a useful example for
typeof operator:
inferring some macro argument type.
But there's a more useful and immediate side to it,
like Go's
:= and C# var: <code>auto</code>.
auto i = 3;
While this is nowhere close to the full listing of quality of life features,
I'll stop here.
The main point is delivered: C might be quite readable,
and there's a whole software ecosystem exploiting it—Suckless.
In case you have an impression that C is undecypherable,
you might enjoy checking out modern C.
Especially with the
awesome changes introduced with C23!
This website is
and generated with the help of
You can view page sources by appending .h to the page URL.
Copyright 2022-2024 Artyom Bologov (aartaka).
Any and all opinions listed here are my own and not representative of my employers; future, past and present.