
\documentclass[12pt]{article}
\usepackage[T2A,OT1]{fontenc}
\usepackage[default]{cantarell}
\usepackage[a4paper, top=20mm, bottom=20mm, left=20mm, right=20mm]{geometry}
\usepackage[utf8]{inputenc}
\usepackage[russian, english]{babel}
\usepackage{tabu}
\usepackage{hyperref}
\usepackage{parskip}
\usepackage{graphicx}
\usepackage{tabularx}
\usepackage[normalem]{ulem}
\usepackage{float}
\floatstyle{boxed}
\restylefloat{figure}
\usepackage{setspace}
\onehalfspacing
\author{Artyom Bologov \href{mailto:making-c-prettier@aartaka.me}{(email)}}
\date{\today}
\title{Making C Code Prettier}
\makeatletter
\def\endenv{\expandafter\end\expandafter{\@currenvir}}
\makeatother
\begin{document}
\maketitle

C has a bad rap for being unreadable.
I've already explored
\href{run:making-c-uglier}{the ways it can get worse,}
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.

\section*{Test Program} \label{test-program}

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.

\section*{Good Code Style} \label{style}

I know I listed indentation styles as ugly
\pageref{indentation-bracket-placement}{in the previous post}.
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.

\section*{Non-Bracketed Blocks (pre-ANSI)} \label{non-bracketed-blocks}

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.
\begin{figure}[h!]\begin{verbatim}
void
tdefutf8(char ascii)
{
    if (ascii == 'G')
         term.mode |= MODE_UTF8;
    else if (ascii == '@')
         term.mode \&= ~MODE_UTF8;
}
\end{verbatim}\caption{A function from st using non-bracketed blocks}\end{figure}

Looks quite Pythonic to me. Do we need Python if we have this in C?

\section*{More Readable Types and Constants (C99)} \label{types-and-constants}

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—
\href{https://cplusplus.com/reference/cstdbool/}{stdbool.h}
for booleans,
\href{https://cplusplus.com/reference/cstdint/}{stdint.h}
for fixed width types—to the rescue!
\begin{figure}[h!]\begin{verbatim}
typedef struct {
    Rune u;
    ushort mode;
    uint32_t fg;
    uint32_t bg;
} Glyph;
\end{verbatim}\caption{Snippet with fixed-width types from st.h}\end{figure}

There are more types in this snippet—ushort, Rune, Glyph.
But these are Suckless types.
Still, sane \verb|typedefs| make your code more readable.
Well, if you're considerate enough.

\section*{Compound (C99) and Anonymous (C11) Initializers / Literals} \label{compound-anonymous-initializers-literals}

Python and JavaScript have a readable literal object syntax:
\begin{figure}[h!]\begin{verbatim}
{key1: value1, key2: value2}
[elem1, elem2, elem3]
\end{verbatim}\caption{JSON-like Python/JavaScript initialization syntax}\end{figure}

C has more primitive data structures,
but there are literal initializers that share some of this readability.
\begin{figure}[h!]\begin{verbatim}
// Structure initializers:
{value1, value2}
{.key1 = value1, .key2 = value2}

// Array initializers:
{elem1, elem2, elem3}
{[0] = elem1, [1] = elem2, [2] = elem3}
\end{verbatim}\caption{C99 compound initializers}\end{figure}

Here's initializer-based Surf config snippet (actually part of my setup)
that shows why Suckless software is so readable and configurable:
\begin{figure}[h!]\begin{verbatim}
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 },   },
};
\end{verbatim}\caption{Surf config snippet with compound array initializer (redacted for readability)}\end{figure}

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.

\section*{Generic Dispatch (C11) and Type Inference (C23)} \label{"generic-dispatch-type-inference"}

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
\begin{figure}[h!]\begin{verbatim}
#define print_val (val) _Generic((val), int: printf("%in", val), char*: puts(val))
\end{verbatim}\caption{Example of generic dispatch from C11}\end{figure}

And there is type inference starting from C23:
\begin{figure}[h!]\begin{verbatim}
#define iter (times) for(typeof(times) i = 0; i < times; ++i)
\end{verbatim}\caption{Use of C23 typeof in macros}\end{figure}

That's a useful example for
\verb|typeof| operator:
inferring some macro argument type.
But there's a more useful and immediate side to it,
like Go's
\verb|:=| and
C# \verb|var|: \verb|auto|.
\begin{figure}[h!]\begin{verbatim}
auto i = 3;
\end{verbatim}\caption{C23 type-inferring keyword}\end{figure}

\section*{Conclusion} \label{conclusion}

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
\href{https://en.cppreference.com/w/c/23}{awesome changes introduced with C23!}


\par\noindent\rule{\textwidth}{0.4pt}
\href{https://creativecommons.org/licenses/by/4.0}{CC-BY 4.0} 2022-2026 by Artyom Bologov (aartaka,)
\href{https://codeberg.org/aartaka/pages/commit/a91befa}{with one commit remixing Claude-generated code}.
Any and all opinions listed here are my own and not representative of my employers; future, past and present.
\end{document}
