Low-level language? Depends on who you ask!

Low-level language? Depends on who you ask!

As with many topics that are fundamentally philosophical in nature, the first step is to define our terms and their semantics.

As a starting point, this working definition seems reasonable:

A low-level language is one that provides minimal or no abstraction from a computer’s instruction set architecture (ISA). It typically allows direct manipulation of hardware resources such as memory addresses, CPU registers, and processor instructions, with a strong correspondence between the code and the resulting machine instructions.

Outside of assembly language, very few languages are focused solely on these goals.

Strictly speaking, true low-level languages are rare.

What we often refer to as low-level languages are, in practice, ones that expose both high-level and low-level abstractions.

Such languages introduce higher-level constructs, yet still allow developers to operate close to the metal - preserving, to some extent, the original goals of low-level control.

A brief return to C

Which brings us to C - a language whose history is deeply intertwined with the development of Unix, originally written in PDP-7 assembly.

C represents the culmination of Ken Thompson’s early experiments, starting with the B language (described as “BCPL semantics with a lot of SMALGOL syntax”), which evolved into New B and ultimately became C in 1972.

The design goals of C were clear: retain the ability to interact with low-level abstractions, while offering what assembly could not - structured control flow, richer data structuring facilities, greater readability, and expressiveness.

To quote Bjarne Stroustrup , much like C++, C "was driven by engineering, not by philosophy."

A language for engineers, by engineers - and yet one that drew inspiration from many of the foundational works of the 1960s. (There’s even a traceable ALGOL heritage in C.)

In a remarkable leap forward, Version 4 of Unix, released in November 1973, saw its kernel extensively reimplemented in C - a milestone that cemented the language’s place in computing history.

It’s often forgotten that long before C was standardized by ANSI in 1989 and ISO in 1990, it had already undergone significant evolution.

The 1978 K&R edition captured much of this, but those encountering John Lions’ classic A Commentary on the Sixth Edition UNIX Operating System are often surprised by syntax and idioms that now feel unfamiliar or even archaic.

So, is C still low-level?

Let’s return to our main thread: C and its "low-level" nature.

  • The ability to manipulate low-level constructs is certainly still there - particularly in terms of memory and pointers.

  • But as for CPU registers, compilers have long since ceased honoring explicit control unless they choose to, and the register keyword is now deprecated.

  • And when it comes to influencing the machine code output - once critical in an era when compilers needed help optimizing - this level of control has largely disappeared. Modern compilers are far more capable, and micro-optimizations often lead to unpredictable results across different architectures.

Yes, C still allows manipulation of both high- and low-level abstractions, but when it comes to truly low-level capabilities today, it’s mostly about memory access.

CPU-level behavior - once deterministic and cycle-precise - is now governed by out-of-order execution, speculative branching, deep pipelines, and other microarchitectural complexities well beyond the programmer's direct control.

Even on the data side, C provides no built-in mechanisms for controlling modern cache behavior - a critical factor in today’s performance landscape.

In conclusion

To me, the label low-level language has always been a convenient shorthand - used loosely to describe a language that provides access to both high-level and low-level abstractions.

But in reality, the scope of what we can genuinely control from the source code at the hardware level is now quite limited.

And honestly? That’s not necessarily a bad thing.

 

Stéphane Dalbera

Founder & Manager of Atopos (MoCap & 3D CGI)

3mo

Let's talk a bit about abstraction.

Like
Reply
Steffen Hirschmann

Software Performance Engineer

3mo

Related article from David Chisnall from 2018: https://queue.acm.org/detail.cfm?id=3212479

Hassan Abba MBA

Head Of R&D Architecture AstraZeneca

3mo

Here is my view on increasing abstraction and where we are today

  • No alternative text description for this image
Like
Reply
Stéphane Dalbera

Founder & Manager of Atopos (MoCap & 3D CGI)

3mo

To continue on these 'low-level' topics...

Vijay Srinivasan

Technology Leader |CTO Healthcare startups | C++/Networks l Cyber Securityl Enterprise Architecture

3mo

C (and c++) are low level langs. Very simple - they offer programming constructs and idioms to directly interface into the hardware. We know one can embed ASM code as part of C program when there is a requirement say to interface into memory registers directly. Let's not split hairs folks, its as simple as that :-)

To view or add a comment, sign in

Others also viewed

Explore topics