top | item 13264258

The Resurgence of C Programming

194 points| ingve | 9 years ago |oreilly.com | reply

315 comments

order
[+] jstewartmobile|9 years ago|reply
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|9 years ago|reply
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.

[+] psyc|9 years ago|reply
I agree with you. I've been a C and C++ programmer for decades, and nothing to do with memory safety or leaks has ever risen to the level of prohibitive or even annoying. Ironically, I've had infinitely more grief from fighting hostile garbage collectors, but that's because I'm a game programmer. I quickly dropped Rust upon realizing that the core of the language addresses problems I don't have.

I'm always met with strawman arguments about how I can't possibly write "correct" code. It's a strawman because I don't claim to write correct code. I don't care if Herb Sutter can find 1000 "bugs" in my C++. I care that my users and myself are happy.

[+] pcwalton|9 years ago|reply
> 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?

Have people been actively looking for mistakes in your code to find exploits?

I just wrote a simple throwaway .otf parser in C, which I've been coding in for a decade and a half. After trying to think about all the places overflow due to malicious input could occur, I just gave up and wrote "FIXME: Insecure" over it, pending a rewrite in something better.

In general, I don't see how you can deny that memory safety problems exist. Pwn2Own is a thing.

> 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).

You just explained exactly why all those inconsistencies and ambiguities exist. And we will keep suffering from them as an industry until we decide to move beyond a language from 1978.

[+] stymaar|9 years ago|reply
> 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 agree with that, and most people do even in the Rust community. I don't expect people to rewrite their software in Rust, but if people could stop writing new C code[1], the world would become a better place in the next decades …

> 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.

In 20+ years of C, you never faced a single segfault ?! I'm sorry but I don't trust you. You're basically pretending being the One True God of programming.

[1]: even in a full C project, it's straightforward to write you new code in Rust in separate files, thanks to Rust really good interop with C. Example: https://bawk.space/2016/10/06/c-to-rust.html

[+] Keyframe|9 years ago|reply

    Whenever C gets brought up, people are like, "pointers... memory... dangerous!"
That's actually the point. It's even coded into C2x charter ( http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2086.htm ):

    The new spirit of C can be summarized in phrases like:

        (a) Trust the programmer.
        (b) Don't prevent the programmer from doing what needs to be done.
        (c) Keep the language small and simple.
        (d) Provide only one way to do an operation.
        (e) Make it fast, even if it is not guaranteed to be portable.
        (f) Make support for safety and security demonstrable.
[+] faragon|9 years ago|reply
Also, there is the risk of re-doing everything and getting worse results: e.g. executable/library bloat, code harder to read/understand, interoperability/binding issues, etc.
[+] willtim|9 years ago|reply
From a security perspective, C is inadequate. This is the biggest issue facing our use of the language currently.
[+] pdimitar|9 years ago|reply
IMO it's yes and no.

YES: Because you're right. Small more iterative changes in terms of tightening up the language to allow for more predictable software (and environment like the kernel) can get us a long way ahead.

NO: Because even though you're very correct, there comes a point in any software stack where the expenses of rewriting the whole thing are vastly smaller than the expenses of iteratively reworking it.

I have drifted away from C/C++ a long time ago -- around 10 years. I personally got sick and tired of per-compiler quirks, different precompiler policies, and writing sed scripts to fix messed up preprocessed files, to name only 3 generic problems.

IMO I believe if something between Golang and Rust comes along and brings only their positives to the table, it'll be very worth to rewrite (or make richer version of) a huge amount of legacy tools in them -- especially if they bring extremely easy cross-compiling and strong runtime guarantees.

I don't know enough to claim either way but in my eyes C has been around for a very long time and a good chunk of the complaints are still in place. I'm tempted to think the community had its chance and that it's time something [somewhat] better must replace it.

[+] sbov|9 years ago|reply
How do you define problem? In terms of consequences or mere presence of a bug? If it's consequences, is it plausible that you have had no problems because not enough people are interested in attacking your code? If you say you have never produced a memory/pointer related bug that got past you, then you probably are the rain man.
[+] maxxxxx|9 years ago|reply
I have seen memory errors in large C codebases produced by larger teams. I think C requires a certain level of discipline and a lot people working at large companies simply don't care enough.

From my experience using a simple subset of C++ using things like shared_ptr reduces problems a lot.

[+] Volt|9 years ago|reply
>I've never had a (self-inflicted) problem in that area.

That you know of.

[+] pjc50|9 years ago|reply
"(Self-inflicted)" is an important disclaimer, because it implies that you work mostly on your own from the metal up?

(Also a meta-note about HN discussion: we have years of people saying "there's a problem here" and one guy saying "it's not a problem for me", seemingly unable to see why anyone else has a problem. "Works for me" is not a mission statement.)

[+] bluejekyll|9 years ago|reply
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.

[+] verdax_1|9 years ago|reply
It seems that a few years ago several big name tech companies found themselves at the limit of what they could do with the c#/java style languages. But they weren't willing to go back to c/c++. Facebook started experimenting with D, apple created swift, google created go, Mozilla created rust, Microsoft had a rumored system language that never seemed to materialise, and even c++ is trying to get away from itself.

It is sort of looking like the industry as a whole is starting to see if there isn't a better way to do things and I think we will see how things shake out in the next five years or so.

[+] michaelchisari|9 years ago|reply
For new projects on hardware that supports the Rust compiler, there are few reasons to choose C over Rust.

That said, take the kind of lifelong momentum that PHP has, and multiply it by a few orders of magnitude, and you have C. It will be a very long time before C is replaced by anything.

[+] david-given|9 years ago|reply
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.

[+] mjolk|9 years ago|reply
> As the article states, it's resurgence is bc of restricted small devices, but that's not because it's a great language.

To be fair, it's an amazing language, but if you're coding to get things done with a deadline (or with an unknown set of specs), of course you should go for the nailgun instead of making custom hammers.

[+] CorvusCrypto|9 years ago|reply
I have also been looking to get back into bare metal programming professionally (I miss the torture). Did you see an immediate switch to rust or is this a rare unicorn project in a sea of C/ASM code for embedded devices?
[+] Itsdijital|9 years ago|reply
I am new to programing (well new in the sense that I have been doing it sparsely for years) and only have written code for microcontrollers, is rust a good replacement for C in that domain?

I don't know much about other languages, but it seems C is pretty well tailored for doing all bit-level stuff. Is rust the same way?

[+] buserror|9 years ago|reply
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|9 years ago|reply
> 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 . Your tool might be sharp, but that doesn't mean that you can't make it safer to use.

[+] blub|9 years ago|reply
It's correct to say that C is a more explicit programming language than C++, where each line of code won't have large side-effects in performance or code size.

The consequence is having to painstakingly code everything at a low level of detail though, with only macros and its limited functions to rely on for code reuse. This would be fine for low-level embedded work, but anything other than that is simply painful, unproductive and in my opinion not fun at all. I shudder at the thought of having to manually free resources, to use the embarrassing C strings and arrays or having to write dozens or hundreds of line of code to do one simple thing that C++ can do more safely and also in a highly-reusable way.

C is inadequate and has been for a long time. Its status of mythical, hardcore programming language continues to protect it, but slowly people are becoming more outraged at its inadequacies, as they should be. That's what the fuss is about.

[+] naasking|9 years ago|reply
> 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.

You just answered your own question: most people don't apply sufficient care and attention. So should we leave sharp tools lying around and encourage their use knowing they're going to be abused and cause serious problems?

[+] marcosdumay|9 years ago|reply
> 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.

What do you mean by "footprint" here? Because if it's heap space or CPU, you can certainly have it.

[+] jstewartmobile|9 years ago|reply
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|9 years ago|reply
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.

[+] rb808|9 years ago|reply
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|9 years ago|reply
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.

[+] cryptarch|9 years ago|reply
Try Rust maybe?

It has a different learning curve from C, as initially you'll be having a hard time getting programs to compile at all, but from that point the ergonomics are much better and you don't ever have to deal memory bugs unless you're developing a low-level library.

[+] dwc|9 years ago|reply
> So sometimes I wish I could go back to the old days but my nostalgia is probably rose tinted.

It seems like nostalgia is a big thing over the past few years. Old game emulators, people getting back into C64 or whatever. I guess it's fun for some people. I've considered playing with such stuff, but I know I'd miss some of the real advances we've made since then.

But my major projects at work are in C. My previous job was about 50% C, 50% scripting languages. For all C's deficiencies it's a known quantity and does its job well enough. And knowing C well is a rare enough skill to be valuable, apparently.

When I don't need C I'd much rather reach for something like ocaml/haskell, a lisp, erlang/elixir, or something. Basically I ignore all the "C replacement" languages because I can either use C or pick something way better.

[+] liuliu|9 years ago|reply
The tools and stdlib improved ton too. I had address sanitizer and undefined sanitizer default on for a while and that helped a lot on memory issues. Things such as int32_t, intptr_t, ptrdiff_t made it is easier to be confident about your pointer math as well.
[+] CalChris|9 years ago|reply
Well, C and C++ are very different languages. But going forward, this long time C programmer is writing in Rust unless required by exigencies beyond my control. A gun pointed at my head or writing an LLVM backend qualify. Not much else.
[+] gertef|9 years ago|reply
The reality is that anything you do for the first time is fun, and then gets boring.
[+] overgard|9 years ago|reply
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|9 years ago|reply
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.

[+] TheAceOfHearts|9 years ago|reply
I think that when people say "C is hard", what they usually mean is "writing portable bug-free code with C is hard".
[+] nickpsecurity|9 years ago|reply
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.

[+] bandrami|9 years ago|reply
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

[+] dmitrygr|9 years ago|reply
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|9 years ago|reply
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.

[+] faragon|9 years ago|reply
C is not going away because is useful, simple, beautiful, and has no problems on dynamic linking on most OSs.
[+] agumonkey|9 years ago|reply
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|9 years ago|reply
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|9 years ago|reply
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.

[+] d33|9 years ago|reply
Why would anyone choose C when Rust becomes mature?
[+] SteveWatson|9 years ago|reply
Why do I need to log in to read the article?
[+] catnaroek|9 years ago|reply
> 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?