C Until It Is No Longer C

By Artyom Bologov

IMAGE_ALT
Enjoying C while it is still C. "Pride" by Pieter van der Heyden, 1558

We have to admit that C is inherently/potentially ugly. One can try 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!

Standard Headers: Booleans and Nicer Logic

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!

 #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
Making booleans accessible on every version of the standard

Et voilá! Now we can do proper booleans:

// 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);
}
Using booleans

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 #include away!

 #include <iso646.h>
 #define eq ==
 #define bitnot ~
 #define bitxor ^
iso646 and some more aliases

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

bool
iscontrol (unsigned int c)
{
        return (127 eq c or c < 32);
}
iso646 macro use

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

 #define is ==
 #define isnt !=
Defining (in)equality

And use it like:

return c is 127 or c < 32;
iso646 macro use

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 c = 127, relying on compiler to scream when it sees 127 = c.) After all, the spelled-out operator cannot end up as assignment. Readability and reliability win.

Nicer Types: Fixed Width and Custom Shortcuts

I already mentioned these before. But it never hurts to use these more:

 #include <stdint.h>
Including fixed-width types like int32_t

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

typedef unsigned char uchar;
typedef unsigned char ubyte;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
Defining shorter aliases for standard types

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

typedef char* string;
typedef char byte;
typedef char* bytes;
typedef void* any;
More shortcut/convenience types
bool
iscontrol (byte c) // Or uchar, or uint
{
        return c is 127 or c < 32;
}
Using new "byte" type

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:

 #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
Defining auto-inferred variable definition macros

And use it too!

bool
iscontrol (byte c)
{
        var delete = 127,
             space = ' ';
        return c is delete or c < space;
}
Using type-inferred vars

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 Pretty.C, my project making C even further from God!

Leave feedback! (via email)