
The Resurgence of C Programming - ingve
https://www.oreilly.com/learning/the-resurgence-of-c-programming
======
jstewartmobile
Whenever C gets brought up, people are like, "pointers... memory...
dangerous!" In 20+ years of C, I've never had a (self-inflicted) problem in
that area. Maybe I'm the rain man of bit-twiddling?

What has caused me tremendous grief are all of the inconsistencies in the
compilers, the gotchas of the precompiler, and the ambiguities in the language
itself. C++ is even worse.

Rust is great, but not great enough to justify a redo of a program that has
been extended and maintained for decades (like vim or photoshop).

I think an iterative tightening of the language would be of greater utility to
everyday computing than a rush to re-do everything in something "better."

~~~
pavlov
I always felt that Objective-C was a great take on a "better C"... Definitely
not conceptually better in the ways that Rust is, but simply better for a lot
of the practical things where C suffers the worst.

Obj-C was an appealingly simple extension to C from the compiler point of
view, but for a long time it was hobbled by the runtime/framework situation,
as the NeXT/Apple runtime wasn't open source.

Just as that compatibility hurdle was getting fixed by open source efforts
around 10 years ago, the iPhone happened and Apple went nuts with extensions
to the language... It used to be that Objective-C proponents would brag that
you can learn the syntax in 5 minutes if you know C. Now the language is
filled with uncountable double-underscored keyword warts and @ declarations.
Today's Obj-C looks more like an intermediate format for a Swift->C compiler
rather than an evolution of Obj-C 1.0.

I understand completely why that happened. I just wish that Obj-C had gained
more of an open source foothold when the opportunity was there, so it wouldn't
have been so dependent on Apple's stewardship which eventually killed it as an
independent language.

~~~
WalterBright
Back in 1986 or so, there were two languages based on C: C++ and ObjectiveC. I
was casting around looking for an edge with my C compiler, and investigated
the two.

On usenet, there was about the same amount of traffic in the C++ and O-C
newsgroups, the respective communities were about the same size.

Which should I choose? ObjectiveC was produced by Stepstone, and they wanted a
royalty. C++ was produced by AT&T, and I phoned up their lawyer who said no
royalty was required.

So I picked C++ based on that.

In 1987 I shipped the Zortech C++, the first native C++ compiler, and the
popularity of C++ promptly zoomed. (Yes, I do think ZTC++ had a lot to do with
the crucial early surge of C++ adoption, because the PC was where the
programming action was at the time, not Unix.) The traffic in the C++
newsgroup exploded, and the ObjectiveC traffic crashed.

O-C was dead until Apple picked it up again later.

~~~
tomcam
Dude's not wrong about Zortech's influence, young'uns. It was truly a game
changer. Love the anecdote about calling the lawyer!

~~~
WalterBright
I not only asked him about royalties, I asked him if I could call it "C++". He
laughed, and said nobody had ever asked that before, they just did it. He was
very nice and said I was welcome to use it.

I wish I remembered his name. He was a good guy.

I also remember how nice Andrew Koenig was to me in the early days. All the
C++ people were nice, but Andy was a standout.

------
bluejekyll
Maybe I missed it in the article, but it alludes to this: C is the least
common denominator. It's not a great language, but it works everywhere and
will work in the most restricted of environments.

As the article states, it's resurgence is bc of restricted small devices, but
that's not because it's a great language. Debugging memory issues is horrible,
having strange things happen because of randomness between compilers, no fun.

I had a recent desire to get back to baremetal, but I didn't go back to C; I
have too many battle scars. I went to Rust, and have never looked back or
regretted it. The FFI between Rust and C is pretty easy too for any cases
where I need it.

~~~
david-given
The other big advantage of C is that multiple compilers for it exist that are
good enough to use in real life, for a wide variety of toolchains, and it's
simple enough that it's possible to write a compiler for it (if not
necessarily a very good one) as a hobby project. We can be reasonably sure
that C will continue to exist.

By comparison, C++ has precisely two working open source compilers --- clang
and gcc --- and Rust has _one_ : if you commit to using Rust, you're also
committing yourself to an LLVM-based monoculture. The chances of the entire
Rust team being simultaneously hit by a bus is low... but it's something that
needs to be factored into a product assessment.

~~~
gcr
That argument seems akin to avoiding C# because only MS supports it, or
avoiding Python because CPython is the only serious implementation.

The language with the most sensible implementations seems to be javascript, I
guess.

~~~
pekk
It can be rational to develop projects on new languages. It can also be
rational to consider the risk posed by the ecosystem you are plugging into.
For example, it would be rational to consider the risk to a new project of
basing itself on a language that is only supported by one corporation.
(Imagine if Oracle had become a single point of failure for Java.)

That said, Microsoft has very deep pockets, shows every indication of
continuing to promote and use .NET extensively, and has also built up a lot of
commercial buy-in over the 15 years or so that .NET has existed, which could
carry it forward a while or fuel alternate implementations if something
catastrophic happened.

PyPy is a serious implementation of Python. There are others and have been
others over the years. While the corporate buy-in isn't the same as .NET or
Java, there is a large amount of open source funding and buy-in from very
diverse sources. Python is older than .NET as well.

Maybe the risk of using Rust is acceptable even if a bit larger, or the added
risk is offset by Rust's good qualities - nonetheless, it's a very new
language with no Microsoft-scale company behind it. Not precisely comparable.

It doesn't matter if Rust is perceived as having less ecosystem risk than
Python or .NET, if in (say) 10 years it doesn't make significant headway
against C, which is what it actually has to compete with. Here we could
consider the examples of Pascal and Lisp - they competed with C, were arguably
much better languages, and they lost anyway.

It's something worth considering if your dreams are founded on Rust.

------
buserror
I love C, I really don't see what the fuss is about about 'replacing' it
really. It's a sharp tool, requiring care and attention.

I did C++ for about 20 years, and gradually reverted to C, simply because of
the footprint and the ease of maintaining a C codebase compared to a C++
codebase. C++ codebase's footprint will /explode/ very quickly, while it's
really, really hard to do that with C.

You can't have 'shockwave' effects in C codebases; you can't have an intern
adding a subtle 2 liner to your codebase in an obscure base class and make the
footprint of your application explode. (been there...). It's a lot easier to
review, test and maintain over a number of years.

Also, I've grown up considerably since I believed object oriented programming
is THE way to solve everything related to programming problems, I've seen a
lot of cases where you'd have a spaggetti plate of classes to solve a problem
while you in fact could have solved that problem in a 15 line static function.

C -- especially C99 with it's extensions -- is nice, lightweight, hard to mess
around with. it's actually a sharp tool but at least it's a _straight_ sharp
tool. You know where it's going and how it can hurt you. It's not the case for
many of the other solutions who just add bloat to try to hide the fact that
they are about as sharp cutting, but it'll get you at the back of the head,
later :-)

I keep a keen eye on what's going on with Rust and Go in particular, but it'll
be a long time still for me to commit to any of the new kids on the block.
Right at this minute I imagine myself easily having to rage-recode it in C at
some critical point because of some unforeseen effect.

My only regret with C is that the C committee is completely out there. C11
doesn't solve any of the problems that would be _useful_ for 99% of C
programming. Like, rolling in some of the GNU extensions that have been around
for 25+ years (case X...Y comes to mind!)

~~~
Manishearth
> I really don't see what the fuss is about about 'replacing' it really. It's
> a sharp tool, requiring care and attention.

I really like the take on the "sharp tools" analogy here:
[https://www.schneems.com/2016/08/16/sharp-
tools.html](https://www.schneems.com/2016/08/16/sharp-tools.html) . Your tool
might be sharp, but that doesn't mean that you can't make it safer to use.

~~~
Sanddancer
The C/C++ toolchain has been working to add guards and guides to their sharp
tools. Things like the various sanitizers in the llvm toolset have already
meant that a lot of bugs that would have been released are instead fixed
beforehand. You also have things like OpenBSD's implementation of malloc which
also helps in the software feedback loop in finding logic errors that allow
for things like use after free errors. C still requires attention, but there
are a lot of places where it's harder to cut yourself.

~~~
buserror
I personally use libtalloc [0] for my allocations in C. Small footprint,
excellent feature set, and it has heap checks, reference counting and all the
gizmos you'd like in an allocation library. It's actually awesome, I highly
recommend it.

For C 'gotcha' cleanups, you can use cppcheck of course (highly recommended)
but there's also 'scan-build' the static analyzed from clang.

[0]:
[https://talloc.samba.org/talloc/doc/html/index.html](https://talloc.samba.org/talloc/doc/html/index.html)

~~~
RustyRussell
Love talloc: just taking the opportunity to plug ccan/tal which I wrote after
hacking on talloc for a bit:

[http://ccodearchive.net/info/tal.html](http://ccodearchive.net/info/tal.html)

~~~
buserror
Cool, why the parallel project, if I may ask? What did you find you needed
'better' than talloc? :-)

------
jstewartmobile
Given that clock speeds are pooping out, this makes total sense. Things
already seem to be moving to an even lower level when performance _really_
matters (shaders, FPGAs, etc). C looks fairly forgiving after implementing
things in verilog.

For the "why not X" crowd, the problem is that there are very few Xs out there
with 30+ years of code to build off of. That, and it's almost a psychosis
among us CS grads to overestimate the magic that "better" languages are
capable of.

~~~
nine_k
I don't hear much about performance problems causing major trouble in popular
software and making everyone patch things in haste.

For unsafe memory management errors leading to RCEs it's a different story.
Guess what language are the patches usually in.

~~~
jstewartmobile
Not everyone has the same usage case. For general user applications, yeah,
performance isn't that big of a deal. That's not the entirety of computing
though.

Some people do things where performance is crucial. This is probably why Intel
is moving into the FPGA space and Google is making their own accelerators for
machine learning.

~~~
nine_k
Absolutely. People who write games or audio / video software sometimes even do
hand-written assembly fragments.

The very high-performance things are a relatively narrow area, and an area
where C can easily lose to e.g. Fortran.

Also, for ML stuff you likely don't have a huge entrenched C codebase yet. You
are freer to choose a more expressive language, and only hand-optimize /
rewrite in C a small amount of hot paths.

~~~
shepardrtc
Regardless of what glue language you use to write ML stuff, if you follow it
down to its core, most of it is going to use a BLAS library to do matrix
multiplication. That's where the heavy lifting is. And BLAS libraries are in
C/C++ or Fortran. For example, OpenBLAS or Intel MKL.

~~~
nine_k
BLAS Level 1 was released in 1979, thirty seven years ago.

There was no other comparable language to implement it in besides Fortran. C
was a newcomer at the time, like Rust currently is.

The amount of optimization and edge-case handling work that went into BLAS
since then is enormous.

BTW, Fortran, being mostly aliasing-free, is a safer language than C, and more
optimizaton-friendly.

~~~
Gracana
I thought Fortran's aliasing-free rule was just an assumption of the compiler,
not something that it actually enforced.. so you could very easily write code
that contained aliasing bugs.

------
rb808
I keep changing my mind about C/C++.

I loved my junior days programming in C & C++. It was really fun writing your
own logging framework, container classes etc. OTOH spending weeks looking for
root causes of memory problems was fun the first few years then became an
annoyance.

Higher level languages are much more productive - which was initially great,
but now I feel more like a sysadmin than a programmer. Its a lot of
researching, wiring up and configuring libraries. Probably results in better
results but not as fun as hitting the metal.

So sometimes I wish I could go back to the old days but my nostalgia is
probably rose tinted. I'd love to do it, but I don't think its commercially
productive enough, so I'm skeptical of talk of a resurgence.

~~~
bsharitt
I find myself doing most of my hobby programming in C. I think it kind of
evokes the same thing other hobbyists(like wood working) get by building
something from scratch even though there are easier ways to get close to the
same end result. There's just something fulfilling about building something
with your own two hands as it were and seeing it work.

That being said, I don't think I'd like to do C professionally and I'll
happily stick with languages the manage my memory and have all kinds of
libraries that give me "free" stuff.

~~~
sh_tinh_hair
Agreed. My first choice for a project on *nix is usually in C: it feels like
real coding rather than including half the packages/modules from 'pick your
glue language here' where the opacity is blinding. But many times I'll stop
after working through the first data structures and IPC elements and decide to
go higher level in the interest of time and energy (and for other (younger)
people being able to maintain it).

------
overgard
C has this mystique of being hardcore, but it's not really that hard. I
actually think languages like Ruby are more difficult because they hide so
many (important) details from you. I would agree that C can be _inconvenient_
, but its not hard.

~~~
Vindicis
C's syntax is simple, sure. But there's so many little things that can bite
you in the ass very easily, which is why most people think it's hard. For
production code, if you don't have a copy of whatever standard, and aren't
able to use that to find your answers, you shouldn't be working on that code.

Think of it like this: In python you could be a beginner, and still write
effective code to accomplish your goal. And while it might be slow, you also
avoid having deal with a great many subtleties, which in C, to write code for
a similar function, you could very well need to be high-intermediate to write
the same bug-free code.

Faster? Most likely, but if it's error-prone, does speed really matter?

That's my belief anyway, ymmv.

~~~
elcritch
To reinforce this, I still believe C is one of the most elegant syntax's for a
"portable assembler". There are many dark corners of C, take for example
pointers: [https://kristerw.blogspot.com/2016/03/c-pointers-are-not-
har...](https://kristerw.blogspot.com/2016/03/c-pointers-are-not-hardware-
pointers.html)

~~~
bogomipz
This is an interesting read, thanks. However I do not understand the opening
sentence:

"Pointers in the C language are more abstract than pointers in the hardware,
and the compiler may surprise developers that think that pointers in C work in
the same way as pointers in the CPU."

What are pointers in the hardware? I am not sure what is being said. Any
ideas?

~~~
cesarb
> What are pointers in the hardware?

Under current "flat address space" architectures, a pointer in the hardware is
nothing more than a memory address, represented as an integer. That is, a
pointer with value 0x12345678 is the address of the memory 0x12345678 bytes
above the start of the virtual address space.

In the C language, pointers are more abstract: they have to point to either
within an object, or one past the end of an object. This is because there are
architectures like segmented architectures, where a pointer has two parts
(segment and offset) and cannot be treated just like an integer, and the same
C program should in theory be able to also run in these architectures without
change.

~~~
bogomipz
Thanks for pointing out the alternative of segmented memory, this now makes
sense. Cheers.

------
nickpsecurity
Interestingly, one can substitute Ada/SPARK for C in a lot of this article on
"C's benefits" with huge boost on safety & maintenance side. For cutting-edge,
one project on 8-bit micro's used ATS language for its combo of safety &
performance. OcaPIC let's tinkerers use Ocaml subset for algorithms if
performance doesn't preclude it. People are also getting a combo of high-level
and C benefits by using DSL's embedded in eg Haskell that output C. The Atom,
Ivory, and Tower languages are examples of this.

The only thing that's uniquely an advantage of C in the article is
understanding legacy code in popular projects. It's mostly in C for historical
& social reasons. Mastering C is a great help there. Although, one could still
use Ada (Ada-to-C compiler) or DSL approaches above with better results when
_writing_ code. Maintainers won't accept that in popular projects, though. So,
back to knowing & writing good C for this sort of thing.

~~~
ci5er
So... Ada is better, and anyone could use it where they use C - and in fact
could use it to generate C. But nobody does.

Is that your point?

~~~
Keyframe
There was recently a discussion about Ada here and it seemed real nice with an
obvious question - if it's so nice, why no one is using it outside of scope of
people already using it. So, I gave it a try. Ada is a wonderful, WONDERFUL,
language. Albeit a bit verbose. Here comes the catch though. Everything
related to Ada seems to be tied to Adacore and proprietary toolings. There's a
path for you to do it without (still tied to Adacore though), but not as
obvious and not as widespread. Kind of like Common Lisp in ye olde Franz days.

C is great too. C99 especially so. C11 threads are good too. C20 seems to be
on a good path as well, here's its charter: [http://www.open-
std.org/jtc1/sc22/wg14/www/docs/n2086.htm](http://www.open-
std.org/jtc1/sc22/wg14/www/docs/n2086.htm)

Only thing I would add to C as a language or in standard libraries is some
kind of (better) string and UTF handling. ICU4C is coolio, but too much.
Antirez's SDS looks cool, but I haven't used it, so I don't know from practice
how/if it works with UTF and if it's great in production.

~~~
nickpsecurity
"Everything related to Ada seems to be tied to Adacore and proprietary
toolings. There's a path for you to do it without (still tied to Adacore
though), but not as obvious and not as widespread. Kind of like Common Lisp in
ye olde Franz days."

That's a fair criticism. The comparison to Franz CL seems good, too. The good
news about this risk is that AdaCore at least FOSS'd most of the key stuff.
The compiler also has rigorous validation suite that can be used in an
alternate one. I've always thought it would be better to redo the compiler in
Scheme, Ocaml, or Haskell anyway to use all the wonderful tooling they have
for abstraction, assurance of correctness, and maintenance. Maybe a front-end
that then gets run through LLVM as is getting more common.

~~~
Keyframe
You hit the point I've missed to punctuate. At least Adacore's stuff is
FOSS'd. Well, a version or two away at least. In contrast with Allegro, that's
a huge point forward. Also, at least someone is actively working on FOSS, even
though it's only one company (mostly). That's kind of the only major downside
I saw with Ada when I've tried to answer to myself that question of why isn't
anyone using it outside of people already using it. The other part-answer
would probably be that it's not in fashion, but I'm not concerning myself with
that.

~~~
nickpsecurity
I remember that I loved reading most of what was on Allegro's feature page.
Especially AllegroCache where you put OOP data in an OOP database instead of
the round peg, square hole concept involving a RDBMS & ORM that are popular.
They throw in a Prolog for queries and their own little SourceForge of
libraries. Kept it proprietary at a cost.

It about seemed worth the money albeit I'd keep a FOSS variant of my code on
CLISP or something in parallel just in case. ;) Then I saw the real anti-FOSS:
royalties. They charge royalties!? In (year here) in software!? Their
dependence is reminiscent of Adacore but their financial benefit on
development and distribution can only be topped by Microsoft, IBM, and Apple.
;)

~~~
Keyframe
Those royalties, man. That's some next-level Oracle stuff they had going on. I
always wondered would CL have had more adoption if Franz had abandoned those
and sold tools only. I don't know how Mirai pulled it off. They were using
Allegro, as far as I remember. Though they went bust, but I bet not due to
royalties, hah.

------
bandrami
C was designed in a time when codebases were much, much smaller than codebases
today; when your project got big enough that it was unwieldy for C you
embedded a lisp or TCL interpreter and used that to string together small C
utilities.

As I Get Older™, I'm starting to agree with the Suckless[1] people that the
small-project way is better, and that one of the reasons it's better is that C
still works for it. Projects that are small enough for a single developer to
understand in the nature of things have fewer problems. Yes, that would mean a
change in what we expect software to do and how we expect it to behave, but
that changes all the time anyways, and I think a pendulum swing back in the
minimalist direction would be a good thing.

[1] [http://suckless.org](http://suckless.org)

~~~
kazinator
At one point, there was a pejorative in circulation among some programmers:
"hugeware". It seems to have been forgotten. We seem to have developed a kind
of "hugeware acceptance".

What was dubbed hugeware was actually small by today's standards.

------
dmitrygr
Is it that amazing how best tools for any given job keep resurging no matter
how many times people try to replace them?

Turns out that for many jobs C is simply the best language.

Memory limited? C

CPU limited? C

No OS? C

Need precise-ish control of executed code? C

Want inline assembly you can integrate with? C

New chip/architecture? C

Predictable performance? C

Hm, not surprising after all :)

~~~
colemickens
Except Rust has all of those with significant improvements to the type system,
safety and library/package ergonomics.

I don't use the word "significant" loosely here at all either.

~~~
dmitrygr
When you can fit a rust program that works as a voice-changing dictaphone into
1K of flash on a Cortex-M0, get back to me

------
faragon
C is not going away because is useful, simple, beautiful, and has no problems
on dynamic linking on most OSs.

~~~
curiousgal
I wouldn't say simple. But I agree on the rest.

~~~
faragon
Well, C is simple in comparison to its alternatives. By a long shot, in my
opinion :-)

~~~
naasking
Well then, I look forward to your argument supporting the use of Brainfuck or
programming raw Turing tapes. Can't get much simpler than those options by
your metric!

------
erbo
Maybe it's time to revive this little ditty:
[http://www.poppyfields.net/filks/00259.html](http://www.poppyfields.net/filks/00259.html)

------
agumonkey
I still don't really know how to think in C. After long FP fanatism say, I
ended up understanding more low level patterns through recursive to iterative
techniques, shedding light on how to design imperative patterns. Then stack
reducers, and Forth threaded code. All bringing a bit of safety and bounds to
the LoC.

But I'm still not sure how to design in C.

------
Sir_Cmpwn
C is my favorite programming language, out of the half dozen or so I have
advanced to expert knowledge of. It's the best of the lot by a wide margin.

------
pklausler
Article lost me in its first sentence: "Way back in the early 1970s, learning
C was a rite of passage for many students."

Nope. In the early 70's, all the world's C programmers were still in the same
building. Try the late 70's, when many schools got their UNIX licenses, or the
early 80's, when vendors were all doing their own PCC and UNIX ports.

~~~
ajross
It's an article about writing C code for microcontrollers in the now-hip maker
world, not a history lesson. Beyond the reference you quote, nothing from the
Bell Labs era is treated at all.

~~~
pklausler
Makes me wonder why these microcontrollers aren't using Forth in the first
place if code space is so critical.

~~~
ajross
Can't compile zlib or find a mature IP stack in Forth, probably. The point to
the use of C is that they don't have access to an OS and runtime for more
hipster-approved languages but still want a robust community of libraries.

~~~
bogomipz
>"Can't compile zlib or find a mature IP stack in Forth, probably."

Is there something fundamental in Forth that precludes the ability to
successfully write these?

------
d33
Why would anyone choose C when Rust becomes mature?

~~~
Animats
Rust is much harder to learn than C. Rust is a good language, but, like C++,
it has several levels of abstraction that C does not.

With C++, the template fans took over the language and overcomplicated it. Now
you can't do anything in C++ without some template library. Even C++
enthusiasts admit that template programming is hard. It may even be a
specialist skill that most C++ programmers do not have.

Rust picks up where C++ leaves off in that area. There's so much going on
under the hood in templates that programmers are pushed into a ritual/taboo
style of programming. (That's where you're taught to do something a certain
way, but may not know why.)

It's really hard to kill off C.

~~~
bjourne
Rust also has templates (or features that work like C++'s templates) and they
are just as complicated/powerful. For example, here is a Rust function for
inserting or updating a key in a map:

    
    
        fn insert_dup<K, V>(map: &mut BTreeMap<K, Vec<V>>, k: K, v: V)
            where K: std::cmp::Ord,
        {
            map.entry(k).or_insert_with(Vec::new).push(v);
        }
    

The same function in C++:

    
    
        template <typename K, typename V>
        void insert_dup(std::map<K, std::vector<V> > &map, K k, V v) {
            map[k].push_back(v);
        }
    

The C++ code is shorter because if the "magic" operator[], otherwise they are
roughly the same. Imo, templates are very useful because otherwise you can't
make efficient statically typed containers.

~~~
umanwizard
You only gave an example of generics, which a lot of languages have including
Java, C#, etc.

C++ templates are unique in that they let you do a lot more than that; for
example, you can have a different implementation for one specific type.
std::vector<bool> is implemented differently from any other std::vector<K>.
You can also have templates over values, not just types; so you could define
some T such that T<5> differs from T<6> in some way.

I don't know rust; does it allow stuff like this?

~~~
steveklabnik
We do not yet have type-level integers; they are highly desired by a subset of
Rust programmers, and there is an open RFC.

~~~
raphlinus
And for programmers who are desperate to use type-level integers, there exists
typenum, which is an encoding of integers in Rust's type system. They can also
be used to parameterize array length (the generic-array crate), one of the
main uses of such a beast.

That said, I am also looking forward to true type-level integers; they're
needed for the truly proper translation of fixed size arrays in the Fuchsia
IDL (fidl).

------
SteveWatson
Why do I need to log in to read the article?

~~~
nickpsecurity
Either it's a glitch or you don't use NoScript. I got the whole article plus a
message about all kinds of scripts blocked. :)

~~~
hyperpallium
Thanks; just turning off javascript works too.

------
catnaroek
> Some of the most popular and widely used software—like the Linux kernel,
> Apache HTTP server, and Google Chrome browser—are written in C/C++

What is this C/C++ language he talks about?

