
\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:c-not-c@aartaka.me}{(email)}}
\date{\today}
\title{C Until It Is No Longer C}
\makeatletter
\def\endenv{\expandafter\end\expandafter{\@currenvir}}
\makeatother
\begin{document}
\maketitle

We have to admit that C is
\href{run:making-c-uglier}{inherently/potentially ugly}.
One can try
\href{run:making-c-prettier}{making it prettier},
but there’s only so much one can do to C without compromizing its nature.
That’s what I’m going to do here—stretching the limits of what C is, introducing some prettier things.
If you’re a C programmer (like me), you might end up horrified by what I’m doing.
Otherwise, sit back and watch how readable C can become!

\section*{Standard Headers: Booleans and Nicer Logic} \label{standard-headers}

C23 made booleans part of the language.
Which is a good direction.
But what if I don’t want to wait for C23 to be rolled out in GCC or Clang?
Well, I can always define some booleans myself!

\begin{figure}[h!]\begin{verbatim}
#if (__STDC_VERSION__ >= 199901L \&\& __STDC_VERSION__ < 202000L)
#include <stdbool.h>
#elif __STDC_VERSION__ < 199901L
#define true  1
#define false 0
typedef int _Bool;
#define bool _Bool
#endif
\end{verbatim}\caption{Making booleans accessible on every version of the standard}\end{figure}

Et voilá!
Now we can do proper booleans:

\begin{figure}[h!]\begin{verbatim}
// Check whether the char is a control one
// Yes, I know of iscntrl, bear with me
bool
iscontrol (unsigned int c)
{
        return (127 == c || c < 32);
}
\end{verbatim}\caption{Using booleans}\end{figure}

Yes, implicit conversion to booleans.
Because booleans are nothing but unsigned integers 1 and 0.
Now what doesn’t work for me is this ugly double vertical bar.
I want some Pythonesque boolean logic!

It turns out I can have this nicer boolean logic, just one \verb|#include| away!

\begin{figure}[h!]\begin{verbatim}
#include <iso646.h>
#define eq ==
#define bitnot ~
#define bitxor ^
\end{verbatim}\caption{iso646 and some more aliases}\end{figure}

I’m also defining some missing bits and fixing the inconsistently named
\verb|xor| and \verb|compl|.
With these, \verb|iscontrol| becomes even more readable!

\begin{figure}[h!]\begin{verbatim}
bool
iscontrol (unsigned int c)
{
        return (127 eq c or c < 32);
}
\end{verbatim}\caption{iso646 macro use}\end{figure}

\verb|eq| feels sligtly off here.
Why not define another macro for it?
A couple of macros, actually.

\begin{figure}[h!]\begin{verbatim}
#define is ==
#define isnt !=
\end{verbatim}\caption{Defining (in)equality}\end{figure}

And use it like:

\begin{figure}[h!]\begin{verbatim}
return c is 127 or c < 32;
\end{verbatim}\caption{iso646 macro use}\end{figure}

Notice that I switched the order of arguments to a more intuitive one.
Putting a constant before the equality operator is no longer necessary.
(C programmers do that to avoid typos like \verb|c = 127|,
relying on compiler to scream when it sees \verb|127 = c|.)
After all, the spelled-out operator cannot end up as assignment.
Readability and reliability win.

\section*{Nicer Types: Fixed Width and Custom Shortcuts} \label{nicer-types}

\href{run:making-c-prettier}{I already mentioned these before (section types-and-constants)}.
But it never hurts to use these more:

\begin{figure}[h!]\begin{verbatim}
#include <stdint.h>
\end{verbatim}\caption{Including fixed-width types like int32_t}\end{figure}

And then, we can go even further, inspired by brevity of \verb|uint8_t|:

\begin{figure}[h!]\begin{verbatim}
typedef unsigned char  uchar;
typedef unsigned char  ubyte;
typedef unsigned short ushort;
typedef unsigned int   uint;
typedef unsigned long  ulong;
\end{verbatim}\caption{Defining shorter aliases for standard types}\end{figure}

Going even further, here are some more Go-inspired types:

\begin{figure}[h!]\begin{verbatim}
typedef char*          string;
typedef char           byte;
typedef char*          bytes;
typedef void*          any;
\end{verbatim}\caption{More shortcut/convenience types}\end{figure}

\begin{figure}[h!]\begin{verbatim}
bool
iscontrol (byte c) // Or uchar, or uint
{
        return c is 127 or c < 32;
}
\end{verbatim}\caption{Using new “byte” type}\end{figure}

\section*{Type Inference} \label{type-inference}

Another nice-but-not-quite-C thing C23 added is... type inference!
You may disagree with this decision, but it certainly is nice to have.
So let’s add it:

\begin{figure}[h!]\begin{verbatim}
#if defined(__GNUC__) || defined(__GNUG__)
#define var   __auto_type
#define let   __auto_type
#define local __auto_type
#elif __STDC_VERSION__ > 201710L || defined(__cplusplus)
#define var   auto
#define let   auto
#define local auto
#endif
\end{verbatim}\caption{Defining auto-inferred variable definition macros}\end{figure}

And use it too!

\begin{figure}[h!]\begin{verbatim}
bool
iscontrol (byte c)
{
        var delete = 127,
             space = ' ';
        return c is delete or c < space;
}
\end{verbatim}\caption{Using type-inferred vars}\end{figure}

Okay, I should probably stop here.
Both because the example is no longer improvable.
And because most of the readers are already hemorrhaging.
Sorry!
I could’ve promised I won’t do it again, but alas.
Have a good rest of the day with this newly acquired phobia.

Oh and check out
\href{https://github.com/aartaka/pretty.c}{Pretty.C},
my project making C even further from God!


\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}
