embedded software boot camp

C: The Immortal Programming Language

Thursday, February 22nd, 2018 by Michael Barr

Barr Group’s 2018 Embedded Systems Safety & Security Survey is now closed and I am in the midst of analyzing the data. This year a portion of my analysis is focused on multi-year trends. One trend that really stands out to me is that the C programming language refuses to give up the ghost.

A longitudinal study of survey data spanning almost a decade and a half shows that C remains the primary programming language of embedded software. Remarkably, in that time C has actually gained market share from 50% to about 70%–at the expense of assembly, C++, and Java.

The graph below shows the relevant data from 2005 through 2018. The first decade of this data is drawn from annual surveys published by the publishers of Embedded.com with the most recent data coming from Barr Group’s annual survey. Each of these surveys of embedded systems designers phrased the relevant question similarly, either “My current embedded project is programmed mostly in [pick one]” or “What is the primary programming language for your current project? [pick one]”.

Language Use Trend Plot

It makes total sense that the use of assembly language as a primary programming language is falling. The last time I wrote an embedded program mostly in assembly was about twenty years ago. Of course, there will always be some low level code that needs to be written in the native language of the machine–if only to bring up the higher-level language execution and for drivers and kernel code. But with inexpensive (and mostly 32-bit ARM-based) microcontrollers increasingly at the heart of our systems there’s no sense wasting time coding the application code in assembly.

We can attribute about 7 percentage points of the growth in use of C to the reduction in use of assembly during these years. This trend has helped use of C grow to about 60%.

But what’s also been happening in this time is that C++ has failed to capitalize on earlier gains. The peak year for C++ use was apparently 2006, when it had 33% share. Use of C++ as the primary language has since fallen and thus added about 10 percentage points to use of C.

I didn’t include Java in the graph, but it’s use has been less common than assembly in every survey year, with high points of 3% and now down around 1% the last three years. And no other language has emerged to maintain greater than 1% share.

What I make of all of this is that C remains the most cost-effective way to write embedded software. In hindsight, object-oriented languages have been tried but failed to establish their value to most programmers. C++ is a player but looks unlikely to ever eclipse its namesake.

What do you see in the data?

Tags: , , ,

10 Responses to “C: The Immortal Programming Language”

  1. Andrew Mellinger says:

    Thanks for doing this survey! I am always interested on how these things change over time. However, I was surprised that you suddenly jumprf to “What I make of all of this is that C remains the most cost-effective way to write embedded software.” Can you show your data that talks about cost and effectiveness? How do you rate effectiveness? I’d like to see the trends of C vs. C++ vs. Assembly on these scales. I ask because many time we chose languages based on constraints that are not about cost or effectiveness. Can you please substantiate that claim? Thanks. -Andrew

  2. andre says:

    I wouldn’t call c++ an “object oriented language” unless you meant it in the pejorative sense.

    C stays where it is because for the most part, it’s predictable and has few dependencies compared to c++… maybe some day Rust will take its place, who knows…

  3. Observer says:

    Excellent article, thanks. I’m looking for some advice :)
    I’ve worked with Arduinos about ~1 year (multi-node nRF24, HC05, MPU6050 and stuff). Then I’ve learned about Arm Cortex M with two online courses (busy-wait and interrupts, Timers, UART, SSI, ADC, DAC, designed a game (space invaders), connected to net server via ESP8266)
    I found out that my knowledge of C is limited. What’s the next step for me? I’m a controls engineer (EE) and my language proficiency is like MATLAB > Java > C > C++ (I barely know it)…
    I know I should learn C properly. But what about a higher level language? Nobody seems to like/advertise Java… So I should also learn C++ alongside C…But there is also Rust in the options and everyone is saying it has a bright future and C++ is a mess…I’m quite confused at the moment :\
    My interest is in Robotics, Control Systems and Motion Control
    I’d be grateful if someone could share his/her vision/experience with me. Thanks

  4. James Horton PE says:

    C is, was and shall ever be. If you remove the ‘hype’ and media buzz, there is simply no other language that has
    the diverse utility and control C yields. Embedded dominance is natural for C. Even in clusters, we are dicovering
    that small, concise processor kernels and diverse frameworks are all possible with C. Look for ‘Uni-kernels’ for
    clustsers to become embedded C engines…..

    Only a few can ‘C’ forever, but they will dominate, particularly with robust security.

    sincerely,
    James Horton PE

  5. Chris says:

    Any thoughts on the possibility that Rust could take over off in the embedded world notably thanks to it being both a system level language and its inherent safety?

    • Odin Holmes says:

      Rust is one of the few languages which does not ‘hard code’ things like threading model or memory management into the language, which makes it a viable player. On the other hand on the bare metal/resource constrained end I don’t know that the borrow checker is as useful as it might initially seem as there is a lot less if any, heap use.
      In my work I use C++, at the end of the day I have a pretty good idea of what the assembler should look like, I don’t want to write in assembler because no one else can read it and I will just shoot myself in the foot all day. In C++ I can use the type system to keep myself from all that foot shooting and at zero cost, in rust, I don’t see the same modeling power which C++ expression templates give me. I must admit its been a while since I have looked at rust so it may be in there by now.
      I hope that, as an industry, we move towards safer languages, they only cost more if you do it wrong 😉

  6. Odin Holmes says:

    I have found a growing list of reasons that C++ has had trouble breaking into this domain. The ’embedded’ domain is by no means homogenous and spans a lot of space. In the portion which can assume endless RAM or only requires not leaking resources when out of memory I think C++ is very much the right tool for the job and adoption is all about marketing/bias/legacy stuff. In systems which are memory constrained, hard realtime or where failure is not an option because there is no reporting path to the user we still have homework to do. Exceptions for example often require more RAM when turned on than many chips have, which is obviously a show stopper. There are also a number of things in the standard library or even in the implementation of the core language which do not play well with interrupt service routines.
    We are working on these issues in the committee but I must concede that the critique of C++ being a language which can bite you in unexpected ways in this domain is somewhat understandable. As an example function statics, as in static variables in the body of a function, are guaranteed to be initialized once upon the first call to the function (as of C++11). The following use case however:
    void f(){
    static const my_class = my_factory();
    //use of mc_class here
    }
    where f() can be called from multiple interrupt contexts (e.g. main thread and an ISR or two differen ISR priorities) then there is essentially no way of enforcing that my_factory only runs once without disabling ISRs which causes unexpected jitter.
    The above example is probably not going to be a problem for 99.9% of all programs but it is still theoretically possible. If one purges the language and standard library of all functionality which may not work or have surprising results in the presence of ISRs you basically get this proposal http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3256.html which strips everything down to a small portion of the language. Weighed against the cost of change this may not be worth the effort.

    That being said the real advantage of C++ is its powerfull abstraction capabilities. Jus tbecaus efew current libraries are usable in this domain currently does not mean that we can’t write any. Where C has not changed much since my birth, and therefore there has been little change in the way we code microconzrollers in C since my birth I see huge potential for C++ abstractions and the new paradigms which they allow.

  7. Matt Chernosky says:

    Thanks for this! It’s interesting to see (though not surprising to me) that C++ hasn’t managed to catch on.

    C++ can be pretty hard to learn and if you’re coming from C — as most embedded developers would — not only do you need to learn about object-orientation, but you still get all the “fun” of managing your own memory. Then there is the whole issue of understanding the performance implications of C++ (which embedded developers also seem to stress over) although I’m not convinced everyone with these 32-bit ARMS should be *quite* so concerned. Then there is templating — which probabaly seems pretty foreign — the complexity of keeping up with all the C++ versions. All this is a recipe for fear, uncertainty and doubt.

    Oh, and I haven’t seen too many embedded vendors with C++ example projects ready to go out-of-the-box. If you’re going to use C++ you probably need to buy something or know how to set up the runtime by yourself.

    Don’t get me wrong I think C++ could be great, but I get the reluctance to adopt it.

    I definitely see the longer-term threat to C in terms of safety and security though. How many buffer overflow or use-after-free errors do we need to ship before the business case starts demanding that we don’t let them happen in the first place? Maybe it’ll even be government regulation.

    “Modern” C++ (11, 14, 17) I suspect is one path, although from this data it doesn’t look like developers are going to do it on their own.

    Rust is another intriguing option, especially for bare-metal embedded application, because has no runtime that needs to be set up for each processor type. But it’s pretty tough to learn too.

  8. Kamil Szczygieł says:

    Just to add another “pro-C++” opinion here I wanted to mention that I wrote a C++ RTOS for microcontrollers (ARM Cortex-M) – it utilizes most of the nice C++11 features like constexpr constructors (e.g. for mutex) or variadic templates (e.g. for safely passing any number of arguments of any type to a thread or software timer). And all of that does _not_ require use of heap – you can use static allocation in every case.

    It is working correctly in several commercial projects – it’s not just a programming exercise or a “proof of concept” (;

    As I’m using C++11 for embedded projects since the time it was still called C++0x I think I can add an opinion, that the experience is both easier (polymorphism, RAII, type safety, better expressiveness, less boiler-plate, …) and more challenging (designing proper object-oriented architecture instead of the usual mess you see) at the same time. The learning curve is very steep and it took me some time to “take off” with everything (mainly to shift my way of thinking), but once this was done I never felt the need to go back to C – even for projects which needed to be small (like a bootloader). After all – even if you just compile your “C-like” code in C++ compiler you can get the the several important C++ features for free – like RAII and stronger type checking – so a clean case for me.

Leave a Reply