Thursday, May 10, 2018

C Is Not a Low-level Language

David Chisnall (Hacker News):

In the wake of the recent Meltdown and Spectre vulnerabilities, it's worth spending some time looking at root causes. Both of these vulnerabilities involved processors speculatively executing instructions past some kind of access check and allowing the attacker to observe the results via a side channel. The features that led to these vulnerabilities, along with several others, were added to let C programmers continue to believe they were programming in a low-level language, when this hasn't been the case for decades.


A modern Intel processor has up to 180 instructions in flight at a time (in stark contrast to a sequential C abstract machine, which expects each operation to complete before the next one begins). A typical heuristic for C code is that there is a branch, on average, every seven instructions. If you wish to keep such a pipeline full from a single thread, then you must guess the targets of the next 25 branches.


Consider another core part of the C abstract machine's memory model: flat memory. This hasn't been true for more than two decades. A modern processor often has three levels of cache in between registers and main memory, which attempt to hide latency.


A processor designed purely for speed, not for a compromise between speed and C support, would likely support large numbers of threads, have wide vector units, and have a much simpler memory model. Running C code on such a system would be problematic, so, given the large amount of legacy C code in the world, it would not likely be a commercial success.

Previously: Intel CPU Design Flaw Necessitates Kernel Page Table Isolation.

Update (2018-07-04): See also: Lambda the Ultimate.

3 Comments RSS · Twitter

I think it would be more accurate to say C is a low-level interpreted language.

Which is a big part of the problem. A high-level interpreted language would be much less tightly coupled to its interpreter and vice-versa, allowing big chunks of the low-level plumbing to be replaced wholesale without affecting high-level semantics and thus breaking its users' high-level code.

That said, I can think of two companies who could successfully break the C lock-in: Google and Apple. Both own vast, influential, profitable applications platforms which they control wholesale, so those app developers will go along with whatever sells. i.e. The apps are the commercial success; the language is just what the developers have to go through to get there.

Google's already abstracted away from the hardware C interpreter with Java, which in turn it now has plenty motive (Oracle) to get away from too. And Apple's already discarded much of the C compatibility advantage with Swift, necessitating an eventual replacement of that legacy ecosystem (though since they're just replacing it with more of the same they've got everyone doing the most rework for the least significant benefit).

Ultimately the deadlock will have to break. The cost of continuing down the existing morass much eventually exceed that of radical change, at which point it will be in someone's commercial interests to steal the lead and be the one who defines the new standard for the next 50 years. Look at Apple in the PC space, or SpaceX in the aero one. Change is Cost, but also Opportunity.

Just wish they would hurry up and get it going; we ain't got all century, y'all!

If I had to guess, we'll see Rust used as the replacement for C going forward. Mozilla is heavily invested in Rust for Servo, but if the Wikipedia page for Google Fuchsia is any indication, Google is starting to use Rust as well for their next-gen OS. Aside from IBM, I've yet to see much enthusiasm for Swift outside of Apple, which is rather unsurprising given how immature it is compared to Rust.

@remmah: Rust does look the best of the available options. A modern Algol-descendent definitely has its place, particularly in systems and embedded programming. I do hope it doesn't fall into the same trap C did, of being thrown into high-level apps development not because it’s the right tool for the job but because programmers already have it. A language should be shaped to fit a problem space, not vice-versa.


Also, Swift… yeah. It’s really a replacement for C++; floor polish, dessert topping, and all. Not surprised it can’t mature. Hopefully by the time C gets successfully superseded future generations will have evolved a modern collection of small, composable, task-specific languages that will make Swift’s obsolete-by-design equally redundant too.

“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”—C.A.R. Hoare

Leave a Comment