Do We Need a Replacement for C?
C is a widely used language used to program anything from OS kernels to cryptography libraries. Is it time for a replacement?
The C programming language is even today among the most popular languages in usage despite having been released all the way back in 1972, and having quite a number of limitations and flaws by today’s standards.
This is the key reason why C ought to be replaced. Too much critical software is written in C/C++ which has wide ranging implications. One example is bugs in libraries such as OpenSSL. C is notoriously bad at catching problems such as buffer overruns. C is a language allowing you to shoot yourself in the foot in too may ways.
This may sound strange coming from someone who is an avid fan of dynamic languages. However the issue here is type safety. Dynamic languages such as Python and Julia typically catch wrong usage of types. Such as using an integer in an if-statement. Dynamic languages may not catch problems at compilation time but if they have a strong type system, a lot of problems will be caught at runtime. That matters especially with security. Security vulnerabilities is in large part down to causing undefined behavior, rather than a controlled shutdown.
But if C is so bad, why has it not been replaced already? There are many reasons for that. In part it already has been replaced. Java, C#, C++ and many other languages already have taken over tasks previously done in C.
So this is really more about the kind of software which is left, where C still dominates:
- Operating system kernels. Linux e.g.
- Video codecs
- Shared low level libraries such as OpenSSL
- Unix command line tools such as
Why is C still dominating these areas? Because the alternatives until recently have not been very good. A lot of languages in the 90s such as Java, C#, VB.NET and F# seemed to have been focused primarily on creating garbage collected managed languages. Not a great solution for the examples listed above.
Sure there has always been other statically typed languages such as Ada, Modula-2 etc. However these generally did not try to cater to people’s existing skillset, or could be used easily with existing C libraries.
There has been languages such as D, but it has C++ level complexity which is probably not appealing to C developers. It also has initially required garbage collection which likely makes it unsuitable for many of the areas mentioned. You don’t want a garbage collector to kick in while you are trying to maintain a frame rate.
Go and Rust Shows Possibilities
I think one of the first real signs that there is an appetite for a modern incarnation of C and C++ is the rising popularity of Go and Rust. We see a lot of typical tools that was commonly written in C or C++ in the past now being written in Go or Rust. A plethora of command line tools e.g. are popping up, which have been written in either of these langauges. I cover some of these tools here. You see people attempt to write game engines in Rust.
LLVM: The Missing Puzzle
A big part of the possibilities of providing an alternative to C I believe exists today due to the maturity of LLVM. LLVM means a of the really complicated stuff of generating high performance code and targeting many platforms is solved. It makes language development accessible to a lot more people.
Both Go and Rust gave some inspiration to how C/C++ could be rethought and armed with this inspiration and LLVM, a little cottage industry of possible C replacements are popping up:
- Zig, which I have already covered in some detail here and here.
- Odin, a C replacement looking a lot like Go.
- V language. Another C-like language with heavy Go and Rust inspiration.
What is a C Replacement Language?
To replace C, a language will typically need to be suitable for the niches that C still dominate. Not all types of languages are suited for this. So the languages I have listed have a number of features in common which make the suitable to replace C:
- Existing C libraries are easy to reuse. Ada, Modula-2 etc failed in large part because you could not use them with the large C eco-system effectively.
- Build on established knowledge and conventions. Go was really quick to pick up because despite some syntax changes, the APIs and ways of coding was very similar to a C programmer.
- No Garbage collection / manual memory management. C dominates in areas where you need tight control over memory usage. In this space garbage collection is not going to cut it. That is what has prevented Go from fully replacing C.
- Small binaries. Like C, Zig e.g. allows you to make really small binaries. If you want another language in the embedded space you cannot use a language such as Go which produce large binaries.
- Systems level friendly. You need to be able to manipulate bits and bytes. You need good binary operators and pointers. Lots of languages over the last decades don’t have proper pointers. Java made pointers a swear word, but Go partially brought them back.
- Gradual replacement of C code. Having great binary compatibility with C.
Let us expand on the last point. Nobody is even going to bother starting to replace the existing C infrastructure if it means you need to rewrite the whole program from scratch in one go. One thing that in my experience made it easy to transition from Objective-C to Swift was that I could in fact rewrite one single method at a time, recompile and test the program.
With languages such as Zig you can quite easily do that.
There are many reasons why we should replace C, and the primary reason it has not been done before is that the focus has been elsewhere and the tools have been lacking. This is not the kind of thing one large organization necessarily decides to do. You need it to be easy for a little cottage industry of individuals to try there hand at it. With LLVM as a tool and Go as inspiration that is fully possible today.
Do I personally think C will be replaced? I am not holding my breath. This is a long process, and we don’t have any clear winners yet. Large organizations are not going to jump onto Zig, Odin, V or whatever else comes along until a clear alternative has crystalized.
And what does replace even mean? Cobol is still running a lot of our financial transactions. Yet I think we can say that Cobol has been replaced in the sense that nobody today will deliberately choose Cobol for any new project. And wherever possible people will attempt to migrate away from it.
Likewise a lot of well tested C code will not get rewritten. It will simply linger. But we may in the future reach a point where other languages are simply picked over C for the areas C has traditionally dominated.