Live data from Hacker News

How can C Programs be so Reliable? (2008)

tratt.net

41–50 of 230 posts

Re: How can C Programs be so Reliable? (2008)

#41
post #37

"Once one has understood a concept such as pointers (arguably the trickiest concept in low-level languages, having no simple real-world analogy) " huh? So when you write a letter to someone, you actually attach their house onto the outside of the envelope? No of course you don't. You write their ADDRESS on the envelope. All this lore about how difficult pointers are, is bunk. The syntax of pointers vs addresses vs de…

Sometimes I just write the contents of their house on the outside of the envelope.

You have to admit it is one of the trickier concepts people learn when programming. Once you understand it, it's definitely a "Duh, how else would it work?" moment but getting to that point can take some time.

Re: How can C Programs be so Reliable? (2008)

#42
Walking across a tightrope is a lot easier than you would think. When you're walking on a tightrope you really concentrate on your walking; it's stressful, but not actually hard. Still, I don't think many people would choose to walk across a tightrope when an easier option was available.

Exceptions, meanwhile, allow a counterintuitive but effective strategy for greater reliability. My boss likes to say that the cloud is great because machines fail more often - the point being that rather than the impossible task of making individual machines failure-proof, you instead design systems that can handle the failure of any given machine. Often the best way to make a resilient system is to break the problem into quite coarse-grained blocks, and then define appropriate responses (such as failing a single message and processing others, or retrying the whole block) whenever a given block fails.

Re: How can C Programs be so Reliable? (2008)

#43
post #26

Earlier quoted context omitted.

> Needless to say, calling exit() when a call to malloc() failed wasn't an acceptable recover routine. What do you do when malloc fails? A bit of graceful shutdown and logging seems like it would be in order, but otherwise how do you keep rolling if mallocs start failing? It seems to me like that would indicate something has gone unusually wrong and full recovery is futile.

The most common way to indicate that an error has occurred in a C function is to return non-zero. If this is done consistently, and return values are always checked, an error condition will eventually make its way up to main, where you can fail gracefully. For example: int a(void) { ... if (oops) { return 1; } return 0; } int b(void) { if (a(...) != 0) { return 1; } return 0; } int main(void) { if (b(...) != 0) { exi…

What's the point of propagating all errors way up to main if you're only going to exit anyway? I think we know how to indicate errors in C functions. What to do about specific errors, in this case allocation failures, is a more interesting question.

Re: How can C Programs be so Reliable? (2008)

#44

"[Pointers are] arguably the trickiest concept in low-level languages, having no simple real-world analogy[.]" I'm not sure how "address" is not a good, "simple real-world analogy" for pointers. It may be that I've just internalized enough of the behavior of pointers that I'm glossing over important differences, though... I struggled with pointers long enough ago that I don't remember struggling with pointers.

For a lot of people I think it takes a while to really internalize the ramification of the fact that you can have a pointer to memory you're not allowed to use. (That, plus the way they're used in C as a cheap answer to templates/generics.) I understood that a pointer was an address from the start, but it was still some time before I figured out how to use them correctly.

Sure... but I don't really see that that's a problem with the analogy. I'm limited in what I can do to someone else's house, even if I have the address; an address might persist after the house has been bulldozed and replaced; &c...

Re: How can C Programs be so Reliable? (2008)

#45

Earlier quoted context omitted.

I don't get the sense that there was any attempt to recover from errors - it sounds more like they were enforcing that error checking occurred, by replacing `malloc` with one that just returned `NULL` always. It sounds like the goal was to make sure that one didn't assume `malloc` would always succeed and just use the memory. Indeed, recovery is basically futile in this case and your program is going to shut down pre…

What if you application is the fly-by-wire for an airliner? Can you imagine that there might be better options than just calling abort(3)?

Yes, a better option is to make sure this error cannot happen, by making sure the program has enough memory to begin with. Fly-by-wire shouldn't need unbounded memory allocations at runtime.

There are some applications where you can try to recover by freeing something that isn't critical, or by waiting and trying again. Or you can gracefully fail whatever computation is going on right now, without aborting the entire program. But these are last resort things and will not always save you. If your fly-by-wire ever depends on such a last resort, it's broken by design :-)

Re: How can C Programs be so Reliable? (2008)

#46

Tarsnap is the classic example of a C program whose reliability almost defies belief. Its codebase is large; it solves a very hard problem; and it manages to handle almost every cornercase flawlessly. (As of the latest version, it seems to handle every cornercase flawlessly, as far as I know.) But I've always wondered: if Colin were as experienced with Python as he is with C, would Tarsnap be better served by writing…

The traditional argument for high level languages is that you can try many more things in the same time, and that you can focus more of your cognitive faculties on the business problem at hand.

But C guides you to simplify, and gives you control. Combined with the right certain amount of taste this can lead to exceptionally good outcomes. See also qmail, plan 9, etc.

Re: How can C Programs be so Reliable? (2008)

#47

"[Pointers are] arguably the trickiest concept in low-level languages, having no simple real-world analogy[.]" I'm not sure how "address" is not a good, "simple real-world analogy" for pointers. It may be that I've just internalized enough of the behavior of pointers that I'm glossing over important differences, though... I struggled with pointers long enough ago that I don't remember struggling with pointers.

For a lot of people I think it takes a while to really internalize the ramification of the fact that you can have a pointer to memory you're not allowed to use. (That, plus the way they're used in C as a cheap answer to templates/generics.) I understood that a pointer was an address from the start, but it was still some time before I figured out how to use them correctly.

You've never arrived at a physical address to find a shuttered business or gaping crater? I can understand the syntax of pointers being confusing, but the concept has distinct real world analogies. (That being said, I find the syntax of physical addresses in other countries to sometimes be confusing.)

Re: How can C Programs be so Reliable? (2008)

#48
Speaking as someone who has been a long time coder in C and Java, I think the point he makes about checking errors is BS. You have to handle exception in Java and you're perfectly free to consider all the possible failure paths if you want though typically you'll handle the ones you can sensibly do something about and ignore the rest (i.e.: log or just fail outright depending on context). I do NOT miss the C world where you have to handle the results of every single function call if you want to be safe. The exception handling approach IMO is generally superior - the normal code executes simply and the exception handling code gathers all the exception cases together. Much better than interspersing both and especially better than handling the same error 10 times in a row rather than just doing it once.

That said, I love C. It's a very simple language and that's a virtue.

Re: How can C Programs be so Reliable? (2008)

#49
There are multiple factors that contribute, but here's a few that I haven't (to the best of my recollection) seen mentioned so far: tooling (crucial), "do the simplest thing that could possibly work" attitude brought about by (lack of) a built-in collections library and simple syntax, and lack of rapidly changing requirements during development.

Tools for C are powerful, mature, and available on near every platform. Every single C programmer that I know uses multiple memory debuggers, for example: e.g., valgrind for leak checks and more on smaller code segments, LLVM address sanitizer on unit test runs, jemalloc or tcmalloc/google-perftools, and more.

"Do the simplest thing that could possibly work" is somewhat close to the author's point: simply put, while there are widely used cross-platform hash tables in C, it takes more effort to use one; hence, they aren't used e.g., when N is known to be 100 (or if maximum size is bound, there's likewise no pressure to use the built in hash table/red-black tree and one can use perfect hashing instead...). In another big distinction I see between code I wrote in C vs. higher-level languages is that one can simply use a stack allocated variable length array -- or (if random access doesn't happen) a linked list in place of a heap allocated resizable array.

These exammples, I think demonstrated how C discourages you from interpreting "the simplest thing that could possible work" as "the thing that is fastest to code"; that's not to say development speed is not an issue -- it's a _huge_ issue! -- but it often leads to code where the unneeded complexity (such as using a red-black tree or a skip list instead of a sorted stack allocated array!) is hidden from the programmer but is nonetheless present.

Onto the last point, I agree sentiment expressed by others questions the premise. I think the examples of C programmers where we explicitly know of something as being a C program are heavily biased towards well known and open source software; open source software, language runtimes, operating systems, browsers (usually in a clean and limited subset of C++ like, e.g., Chromium and likely Firefox as well -- I only mention Chromium as I've re-used base libraries from its codebase), and so on. We don't, however, think of parking meters, vending machines, and many other usually embedded (but not life critical) systems that -- unlike open source systems software -- are built from unclear, confused, and ever changing business requirements ("well, this city introduced a new red-zone, so now we have to make sure to charge extra 0.33 cents between hours 8 and 13 except on all Holidays, but not July 4th").

Yet when people bring up Java, it's easy to forget about gmail or Minecraft, but instead to think of the insurance claim management system that you had to use after your rental car got rear-ended near 4th and Harrison, that crashes with a user-visible stack trace when you click the wrong button and (even in 2013) doesn't use Ajax and requires opening a new page (slowly, as they don't use Java's built in thread-pools but spawn new threads, because the system has to run at a customer site that uses Enron's custom implementation of Java 1.3 on an AS/400) to make an changes.

Re: How can C Programs be so Reliable? (2008)

#50
post #19

Earlier quoted context omitted.

It depends on the problem you're trying to solve, I think. Let's consider a command line application that fetches a URL, like wget. Without exceptions, you would check the return code of all the system functions you call (dns, sockets, etc), and if any of them fail you can't really recover. You just write out an error message and exit. With exceptions, you could wrap the whole thing and if any system function throws…

But what if the exception was in your code and not the system call? This is incredibly dangerous. Monads are perfect for this. Really combines the best of both worlds without all the unspecified/undefined behavior.

You could always write Monads in C... http://blog.sigfpe.com/2007/02/monads-in-c-pt-ii.html
Post reply on HN