State of C Programming Language in 2019

In four years’ time, C will reach its 50th birthday, an anniversary also shared with PL/M and Prolog. Unlike those two, C remains immensely popular, it’s in the top ten of virtually every programming language popularity survey.

Linux is mostly written in C. Python‘s CPython implementation, Perl, Matz’s Ruby, about half of R, the MyISAM code for MySQL and even the first Java compiler were all written in C. The kernels of most operating systems (including Windows, Mac, Linux, iOS and Android) all feature C.

Now we have a new C standard, C18, that was ratified a few months ago. A mere 198 Swiss Francs will buy the ISO/IEC 9899:2018 standard, all 520 pages of it; you can view the final draft of it for free, though, on openStd.org (PDF) to get a sense of the document. It’s only really of use if you are a compiler writer who wants to be 100 percent conformant, or just curious.

There’s nothing new in C18, just more fixes, so it’s very much a continuation of C17. The last major changes to C were in C11, and those included variable length arrays, multi-threading support, better Unicode support, anonymous structures and unions, and a lot more.

C Holds Its Own Against C++

C++ has made some inroads into C’s arena, especially since the C++ move semantics were added in C++11. When used in the right way, particularly with pointers to large objects, this results in better performance, fewer temporary copies, and lets C++ be used in places that were traditionally C territory (e.g., embedded).

However, C++ compiled code is still generally a bit larger than that of C, because exception handling adds bulk and the number of inline template classes whose members get included.

Out of curiosity, I compiled this in release mode in Visual C++ 2017:

#include 
int main()
{
    std::cout << "Hello world" << std::endl;
    return 0;
}

That compiled to a 10,752 bytes exe. The equivalent C program is:

#include 
int main()
{
    printf("hello world\n");
    return 0;
}

 

That was 9,216 bytes long, or 85 percent of the size. Not a great deal of difference, but I could project this difference growing once you add in other classes.

Code size is important because of the increasing number of Internet of Things (IoT) devices and the use of microcontrollers, which typically have RAM and ROM (Flash) measured in kilobytes. In the embedded field, C has actually gained market share between 2005 and 2018.

C is the Lingua Franca of Programming

C is the programming “common language.” Many programming-language compilers output C source code and let a C compiler do the heavy lifting of generating code (there are around 60 open-source compilers listed on this Github project page; there are also a few targeting C++, as well, but the C ones dominate). It’s not difficult to understand, as C is the lowest-level portable language (the only one lower, assembly language, is tied to a CPU family).

Using C to Speed Up Languages

One of the most popular languages, standard Python, suffers from speed issues because of its interpreted code and use of dynamic variables. If you are doing numeric processing, then you’ll be aware of the likes of NumPy, SciPy, and so on. NumPy is written in C. The standard implementation of Python is CPython, and so works well with libraries in C (and C++).

An alternative way to speed up Python is by using one of the compilers such as Cython, PyPy, or Nuitka. Read about Python compilers speed tests.

C is Recognized as a Useful-to-Know Language

It’s probably not the first language any programmer wants to learn, but it appears to be popular as a second or third alternative. I’ve also seen it as a stepping-stone to learning C++, which is a superset of C.

It’s a matter of debate whether C++ is in decline, but C is by far the easier to learn of the two languages.

Conclusion

C has definitely earned its place as an infrastructure programming language. There is so much software out there that’s used every day, particularly on Linux, that C will be around for a very long time.

Even though Go and Rust in particular are modern and better languages, C is so embedded in the infrastructure of the internet that I doubt it will ever be replaced. Over half of all active web servers are running Apache and Nginx, both written in C (according to Netcraft).It’s been around for almost 50 years, but C very much has a future.

23 Responses to “State of C Programming Language in 2019”

  1. “Even though Go and Rust in particular are modern and better languages”, what the [expletive] does that even mean? Clearly this [expletive] article was written by some [expletive].
    You will keep this comment if you really stand your position on the subject.

    • Dan Marinescu

      rust is ghost and will die that way, go is interesting, especially because of go routines deterministic/yet transparent deallocation (which btw, you also get in modern objective-c and objective-c++, but c and c++ will be there for quite a while (wanna bet, try a trillion of trillions of good lines of source code, probably not even written by carbon based programmers). rest is chit chat (mumbo jumbo)

  2. “NumPy is written in C”
    NumPy is not “written in C”, it uses C as a glue, because C is “lingua franca”, but if you try to build NumPy, you’ll see LAPACK inside and thus Fortran.

    “Even though Go and Rust in particular are modern and better languages”
    Go can be slow as hell (with its low latency GC), cannot be used in unhosted environments and is liked mostly for its simplicity, while Rust is still morphing fast enough to scare the managers off, preventing it from being adopted.

    *facepalm* *facepalm* *facepalm* all the way.

  3. Robi Herb

    You mention PL/M. The implementation by Intel / OS Isys II comes even nearer to ASM in efficiency but without ASM knowledge…

    I always liked the implementation of the case statement, you cannot be more efficient and in the same time you risk a crash, if you do not understand the produced ASM output.

    C has many things in common with PL/M but is more save, bacause Intel needed a compiler for the 8008 CPU, at this time 16k EPROM + 1 k Ram was a big machine.

    Anyway PL/M is basically a stripped down PL/I (IBM) that is
    based on ALGOL.

  4. SeattleC++

    In the hello world example in the article, you are really measuring the sizes of the C and C++ formatted I/O code libraries. If you use puts() instead of printf(), the C example gets a lot smaller. There is probably no supportable assertion you can make about relative code sizes from this example.

    • Have to agree. A real world example would do some substantive things in procedural C, then create some classes (preferably with lots of virtual methods) to do the same thing in C++. I’m sure there are plenty of examples of that floating around on the ‘net.

    • David Gray

      The author admitted as much as that you cannot infer much about code size from the “hello, world” example. Furthermore, the final answer depends largely on choice of runtime libraries. If you use the multi-threaded shared runtime library, MSVCRT.LIB, the runtime code is part of the memory footprint, and is quite significant, while static linking trades a slightly large code size for a much smaller memory footprint for the executing process.

      Of greater significance is the comments made by the author about the bloat added by C++ templates that expand inline, which is amplified many times when code relies on the Standard Template Library or Boost, both of which rely heavily on inline template expansion.

      C is not entirely immune to such effects, since inline functions and macros bloat the code generated by a C compiler in the same way that templates bloat the code generated by C++ compilers. Thankfully, inline functions must be chosen deliberately by a developer, and are probably less common for that reason. Macros are more problematic, because some common library functions can unexpectedly yield inline code unless you are mindful of your compiler options. Even something as common as strlen() is expanded inline in certain circumstances.

      Undoubtedly, C is the lingua franca for good reason, and will remain so for many years, perhaps long after it falls into disuse by carbon units, for the same reason that Latin remains relevant among educated speakers of English and other Western European languages.

  5. John Doe

    correction: linux, any unix, including macos and windows are written in c. same about all iot devices, firmwares and most low latency large scale applications (some indeed written in c++)
    so, world is running on c, and will be doing so, for quite some time. naturally, for vcr and washing machines sunday programmers (using things they call by programming languages, e.g. html, css, javascript, python, perl, bash, java) world will be running on their scripts (trying to be polite)
    perhaps, the only exception is go(lang)

  6. Dan Marinescu

    most of the other programming languages (including even go) are resulted from c, well, more or less. c++ distinguished by giving you more idioms and power of abstraction without sacrificing memory blueprint and performance. go is coming with interesting concepts, given to his mail father (ken thompson, also inventor of unix, among other things). lamentable toys like html, css are not even programming languages. cheap (yet practical) improvisations like javascript, python, php, even ruby, well, same thing. of course, certain improvements were done in java, scala, kotlin, c#, f#, you name it. they will not last (to use bill words)

  7. Dan Marinescu

    sql and any specialized derivatives are also nice toys for invoice flippers (not core software engineers, more like in-house programers, today called by developers or something)

  8. Dan Marinescu

    no way you can write good c code (embedded or not) unless you fully understand the underlying hardware/machine. extrapolating further, no way you can write good c code unless you fully understand underlying assembly. further on, no way you can write good c++ code unless you fully understand how this would be done in c. there would be more to it, separating between physical and logical language representation, but these are yours to discover, if you ever walk that path

  9. Dan Marinescu

    rust is a ghost and will die that way, go is interesting, especially because of go routines deterministic/yet transparent deallocation (which btw, you also get in modern objective-c and objective-c++, but c and c++ will be there for quite a while (wanna bet, try a trillion of trillions of good lines of source code, probably not even written by carbon based programmers). rest is chit chat (mumbo jumbo)

  10. Walt Karas

    All widely-used C++ compilers have an option to disable exceptions. Not wanting the space overhead of exceptions is not a reason to forgo all of the other C++ capabilities that C lacks.

    • Philip Ouellette

      Dynamic memory allocation is the kiss of death in many embedded applications. And not just because of limited memory resources. Imagine if your app never got rebooted during it’s entire use life and that life extends to several decades. That is the reality that some deeply embedded applications have to operate in.

      Virtually 100% of embedded coding is done with a C/C++ compiler. Successful developers just don’t use the portions of the language that are dangerous in these kinds of situations.

  11. Drop off the std library function and stick up on using c function and the size would not a problem much, besides the power of class in solving complex problem is way to go than the program size.