Lessons to learn from C January 30, 2017 on Drew DeVault's blog

C is my favorite language, though I acknowledge that it has its warts. I’ve tried looking at languages people hope will replace C (Rust, Go, etc), and though they’ve improved on some things they won’t be supplanting C in my life any time soon. I’ll share with you what makes C a great language to me. Take some of these things as inspiration for the next C replacement you write.

First of all, it’s important to note that I’m talking about the language, not its standard library. The C standard library isn’t awful, but it certainly leaves a lot to be desired. I also want to place a few limitations on the kind of C we’re talking about - you can write bad code in any language, and C is no different. For the purpose of argument, let’s assume the following:

I hold myself to these guidelines when writing C, and it is from this basis that I compare other languages with C. It’s not useful to compare bad C to another language, because I wouldn’t want to write bad C either.

Much of what I like about C boils down to this: C is simple. The ultimate goal of any system should be to attain the simplest solution for the problems it faces. C prefers to be conservative with new features. The lifetime of a feature in Rust, for example, from proposal to shipping is generally 0 to 6 months. The same process in C can take up to 10 years. C is a venerable language, and has already long since finished adding core features. It is stable, simple, and reliable.

To this end, language features map closely to behaviors common to most CPUs. C strikes a nearly perfect balance of usability versus simplicity, which results in a small set of features that are easy to reason about. A C expert could roughly predict the assembly code produced by their compiler (assuming -O0) for any given C function. It follows that C compilers are easy to write and reason about.

The same person would also be able to give you a rough idea of the performance characteristics of that function, pointing out things like cache misses and memory accesses that are draining on speed, or giving you a precise understanding of how the function handles memory. If I look at a function in other languages, it’s much more difficult to discern these things with any degree of precision without actually compiling the code and looking at the output.

The compiler also integrates very comfortably with the other tools near it, like the assembler and linker. Symbols in C map 1:1 to symbols in the object files, which means linking objects together is simple and easily reasoned about. It also makes interop with other languages and tools straightforward - there’s a reason every language has a means of writing C bindings, but not generally C++ bindings. The use of headers to declare external symbols and types is also nicer than some would have you believe, since it gives you an opportunity to organize and document your API.

C is also the most portable programming language in the world. Every operating system on every architecture has a C compiler, and they weren’t really considered a viable platform until it did. Once you have a C compiler you generally have everything else, because everything else was either written in C or was written in a language that was implemented in C. I can write C programs on/for Linux, Windows, BSD, Minix, plan9, and a dozen other niche operating systems, or even no operating system, on pretty much any CPU architecture I want. No other language supports nearly as many platforms as C does.

With these benefits acknowledged, there are some things C could do better. The standard library is one of them, but we can talk about that some other time. Another is generics; using void* all the time isn’t good. Some features from other languages would be nice - I would take something similar to Rust’s match keyword. Of course, the fragility of memory management in C is a concern that other languages are wise to address. Undefined behavior is awful.

Even for all of these warts, however, the basic simplicity and elegance of C keeps me there. I would love to see a language that fixes these problems without trying to be the kitchen sink, too.

In short, I like C because C is simple.

Articles from blogs I read Generated by openring

Debanking (and Debunking?)

Crypto advocates kicked off a recent, somewhat politicized, discussion of debanking. Strap in for scintillating banking compliance trivia.

via Bits about Money December 9, 2024

Conjuring a Linux distribution out of thin air

I decided I had to get something with slightly more CPU power than my Thinkpad x230 for a few tasks so I got a refurbished x280, aside from the worse keyboard the laptop is pretty nice and light. It shipped with Windows of course so the first thing I did …

via BrixIT Blog December 7, 2024

Threads Won't Take You South of Market

In June 2023, when Threads announced their plans to federate with other Fediverse instances, there was a good deal of debate around whether smaller instances should allow federation or block it pre-emptively. As one of the admins of woof.group, I wrote ab…

via Aphyr: Posts December 1, 2024