As far as I know, C is by far the most widely used language for low level stuff such as systems programming and embedded. Sometimes assembly is used, but that's when you really need to be close to the hardware.

My question is why doesn't C have any competitors in low level development? It might be my ignorance, but I'm pretty sure that C is the obvious (or possibly only) choice for low level programming.

This is as opposed to high level development, where there are many competing programming languages to choose from.

How can you explain this?

  • 16
    1 word, inertia Jul 17, 2014 at 21:37
  • @dan04 that linked question uses the emphasized (bolded) word prominently; this causes the subsequent answerers and voters to become biased (trying to support or refute that claim), while being distracted from the more sensible (pragmatic) reasons. This question is able to attract the more sensible reasons.
    – rwong
    Jul 18, 2014 at 13:26
  • It might be useful to edit your question to clarify to everybody that you're not comparing C to high-level languages, but to other mid-level ones like COBOL and Fortran. I thought it was obvious that was what you're talking about, but all the answers seem to be comparing C to Java and the like. (People on this site need to learn how to read.) Jul 18, 2014 at 22:47
  • 1
    Avoid reinventing the wheel?
    – Giorgio
    Jul 21, 2014 at 14:08
  • I heard that Apple, originally used Object and Class Oriented Pascal ("Mac Pascal") before changing to "Objective C"
    – umlcat
    Jul 21, 2014 at 21:27

8 Answers 8


Interestingly, I've been doing embedded programming for 13 years: 6 in Ada and 7 in C++.

Anyway, there are a number of factors that make C well-suited for this type of programming:

  • The runtime/standard library required is very small.
  • Manual memory management is very useful when memory is limited.
  • Easy to make deterministic/real time because you don't have to worry about when a garbage collector will run or when an exception will get thrown.
  • Easy to assign a variable to a specific memory address, which is crucial in writing drivers.
  • A lot of existing code available.
  • 3
    I didn't know Ada was used much in embedded environments. How does it compare to C for such work? Jul 17, 2014 at 21:51
  • 3
    Ada is used a fair bit in embedded software for the military, or at least it used to be. It's hard to compare to other languages. It's like Haskell where just fixing the type errors at compile time prevents a ton of runtime bugs, but it also gives you a lot of low-level control like C. I prefer it to C or C++, but a lot of my colleagues considered the type system too strong. Jul 17, 2014 at 22:22
  • 6
    Ada is a lot pickier than C when it comes to doing things that are likely to result in you shooting yourself in the foot if you do it wrong. C lets you do it. Ada insists that you tell her that you INTEND to blow your foot to smithereens. Jul 17, 2014 at 23:28
  • 2
    I believe that C compilers are far easier to port to embedded devices. C also has some special syntax for common operations in low-level like bitwise AND/OR (| and &). In the old days pascal was also used for low level stuff, as a matter of fact you can program low level in it right now (on PC), but good luck finding any pascal compilers for your preferred embedded platform. In summary any language that has proper pointers can be used in low level stuff.
    – Hoffmann
    Jul 18, 2014 at 13:00
  • 2
    Ability to insert arbitrary "inline" assembly, or raw machine code, are also a necessity, because the embedded C compiler may not provide full support for the target's instruction set architecture. Also, the ABI or the protocols for making function calls (registers and stacks) needs to be well documented and allow for inter-operation between C and assembly code.
    – rwong
    Jul 18, 2014 at 13:23

In the same way today you might think about browser portability/compatibility (will this code run in Opera!?) people back in the day worried about CPU/architecture portability (will this code run on VAX!?).

So every CPU vendor ended up shipping their systems with a C compiler. It was relatively simple to implement, a lot of people knew C, it performed well, and you didn't have to force your platform's developers to dig into the underlying assembly.

Unlike Javascript though, this momentum wasn't "baked in" to the architecture. C ended up gaining momentum because of its relationship with Unix and the efforts that were undergone to make Unix and C portable across CPUs. You can read a lot about this on C's wikipedia page. In short: Unix was one of the first OS's written not in assembly, but in a higher level language, C. Furthermore C developed explicitly out of attempts to port Unix to other architectures. So those lessons learned helped make C a portable systems langauge. Bell labs created the Portable C Compiler or pcc that made it much easier to support many CPU architectures.

Due to explicit efforts to port Unix everywhere -- C got ported everywhere. So the language was one of the first to have low-level portability baked into its bones and popularity and momentum grew from there.

  • To be picky: Unix was written in assembly, and then when it came time to port it to another architecture, the creators of Unix created C to make Unix easier to port. So, Unix wasn't written in C, rather C was written around Unix, so to speak. Jul 18, 2014 at 15:17
  • 1
    C was the only language for which you could reliably find a compiler, across many systems, in the 80's and early 90s. Compilers were often included in the operating system installations. Jul 18, 2014 at 15:59

Because C is the lowest level portable language that exists and is widely supported.

I remember ages ago in some demo was a comment:

C is just asm with more macros.

And it's true. C is just high level enough to allow writing portable code, but low level enough that you can see what exactly is going on at the level of bytes in memory when you need it and thus can easily connect it to the few assembly bits that absolutely need to be platform specific. And absolutely nothing happens implicitly so when you write nothing, it will take no cycles, which is important when you are writing performance critical things in internals of operating system, threading library and such.

All other programming languages except assembly are higher level. Which is great for writing applications, but for the system code being able to judge what the compiled code with look like is more important.

C is also the least common denominator. You can call C library from any other language. Other languages have various requirements that make mixing them difficult.


To supplement other answers, don't forget that C was written by Bell Labs, largely for the Unix project. Unix itself was rewritten in C the year the language was released. The Unix system tools and libraries were C-based and followed C conventions. In short, C is the official Unix systems language, and today we're all using Unix derivatives (with the exception of the Windows people).

On top of that, anything more high-level than C begins to sacrifice efficiency and programmer freedom for the often commendable goal of safety. For example, try allocating a dynamically-sized block of heap memory in Go. While Go is considered a systems language, it's difficult to do such low-level manipulations in it; you often can't without significant trickery or overhead. Good C programmers are confident in their ability to use the language properly, and don't want to relinquish such complete power and fine-grained control.

  • "With the exception of the 90% using Windows and 9% using Mac, yes, we are ALL using Unix!" "what about Android?" "Doh!"
    – user251748
    Sep 25, 2017 at 16:27

1) ..C is by far the most widely used language for low level.. why?

It is so widely used because of its age. According to Wikipedia - C (programming language) it is 42 years old. It means 42*number_of_programmers man-years of work done. As the C is included in basic programming courses at any serious programming school the number of programmers that can speak C worldwide is very huge and the amount of now available C code is very very huge.

2) ..why doesn't C have any competitors in low level development?..

your claim "doesn't have any competitors" is not true so it does not have any why answer available.

VHDL (start at http://en.wikipedia.org/wiki/Vhdl) is low level language much more efficient for low level stuff. e.g. for expressing the parallelism that can be compiled directly into hardware circuit design or flashed into and "interpreted" with very high speed and efficiency on Field-programmable gate array (FPGA) hardware chips.

This language is not so wide spread as it is not so old, not usually taught at general purpose programming courses, requires special (though cheap) processors to run on. It is more demanding for programmer's discipline and it is not a language for writing a "hello world" applications that just flashes with few LEDs connected to the COM port or to print some fancy ASCII art tables.

VHDL is serious very strong C competitor for low level development. It is not "just another assembler". It is a paradigm shift


In the category of "least common denominator" languages that might replace C something that would be able to efficiently express/compile into MMIX (pronounced em-mix) is a 64-bit RISC architecture designed by Donald Knuth might becom an competitor.


Who nowadays invests the time and effort into inventing new efficient language with tools etc. writing a compiler for it etc. Who needs such an tremendous effort today? What problems would it solve? Even programmers want to raise children, want to have lives. To make such new language widespread it is not solvable as one-man-show-spare-time-hobby-project anymore. Just compare the code bases of various compilers/IDEs with something you know, something you write yourself - and you'll see another answer to the why

  • 2
    VHDL is for circuit design, not firmware design. C and VHDL are two very different beasts. Jul 21, 2014 at 19:35
  • When I worked at company manufacturing LED video boards we used Rabbit microprocessors (C), FPGA (VHDL), Windows PC (Delphi) to implement our "firmware design". The C code and VHDL code ran on special hardware, connected to the PC part through Ethernet and UDP, RDP, TFTP and SNMP protocols. VHDL code was very important part of our firmware design. C vs VHDL=="different beasts"=="paradigm shift". BTW: Intel creates hardware with embedded FPGA processors (VHDL) for Oracle's servers
    – xmojmr
    Jul 22, 2014 at 4:39
  • @DavidPoole BTW: I was coding some Rabbit assembly, some Rabbit Dynamic C and most of the Delphi PC code. In next generation of the video boards all tasks handled by the C code were moved into the VHDL to improve performance (several times), simplify the firmware design, improve reliability and lower the maintenance costs. VHDL is programming language for "..low level stuff such as systems programming and embedded.." as asked by PO
    – xmojmr
    Jul 22, 2014 at 5:21

There are languages competing with C (for low level or system programming): Rust, Cyclone, ... and perhaps Go (which is probably slightly higher level).

And there are more academic languages competing with C.

  • Depends on what you mean by "competing", really. Though there are other languages with low-level capabilities, i haven't heard yet about any of them actually being used to build an OS or firmware from the ground up. And of course, popularitywise, nothing comes close to C. (C++ maybe, but those using it also tend to forbid most of what makes it C++.)
    – cHao
    Jul 21, 2014 at 22:24

Well, the question is what you define as embedded...

Is a Raspberry Pi still an embedded system? If so, then there is competition... You can install Node.JS on it and run JavaScript on it, is it performant? A little bit? Do you care about every circle? (For 10 users (not really)(

So let's say, we only have 33Mhz Do you care about the circles? Yes Likely you could write an Rust - or an Go -Code. But it would give you some cycles tradeoff.. (Security Checks, garbage collection (etc))

Should we care about the GHz or MHz Cycles all the time? Yes and No :)


(Source: embedded developer.)

First and foremost, you need a language that compiles to machine instructions, not some intermediate instructions (e.g., Python, Java). If your compiler builds to Java bytecodes, what runs the bytecodes?

The compiled to machine code requirement eliminates many, many high level languages.

Second, your language needs to compile to machine instructions of multiple platforms. OK, so Haskell can compile x86 and ARM. How about the other dozen CPUs out there?

C's linker gives me a crazy amount of power. I can put code in a specific location. Say my CPU starts up at 0x08000. I can tell the linker to store code at that location. I can tell the linker to store certain code in certain segments. The loader will put those segments in a specific location. That's useful if I have code I want to run out of flash vs code to run out of RAM. The Linux kernel puts startup code into a chunk of memory that is later freed, thus recovering memory from code that's only run once, ever.

I can call assembly from C and C from assembly. CPU startup is all in assembly. Low-low level stuff is done in assembly because the C environment might not be initialized yet! (Something has to call main().) The very low level multiple CPU synchronization constructs (semaphores, mutexes, etc) are usually in assembly because they require specific CPU instructions. Caches, MMUs, etc, are usually configured in fiddly bits of assembly. (ARM is loaded with specific instructions to configure cache, MMU.)

C is a thin layer about assembly. C is faster than assembly. So C wins for low level stuff. C wins because no one else has come up with a competitor.

  • Many days I sure wish there was something better! Jul 21, 2014 at 20:03
  • There are better competitors to C (mostly in the academic world) but the sad fact is that when some academics invent & implement a better language than C, nobody cares and even nobody looks at it. Jul 21, 2014 at 20:37
  • Can you give some examples? I'm genuinely curious. I find C quite frustrating sometimes. Jul 21, 2014 at 22:09
  • 1
    @DavidPoole FreePascal "..can target multiple processor architectures: Intel x86, AMD64/x86-64, PowerPC, PowerPC64, SPARC, and ARM..". Clean language designed by Niklaus Wirth, OOP extensions designed by Borland's engineers (known as Delphi). FreePascal is open source, multi platform compiler of the language
    – xmojmr
    Jul 22, 2014 at 4:31
  • 3
    @BasileStarynkevitch Engineers are risk averse, too. At least those of us who have spent 80-100 hour weeks tracking down obscure bugs two weeks before shipping. Or if you've been face to face with angry customers when your bug breaks their work. :-) Jul 23, 2014 at 14:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.