Live data from Hacker News

How can C Programs be so Reliable? (2008)

tratt.net

21–30 of 230 posts

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

#21

The author makes a good point about the discipline imposed by not having exceptions. Programmers tend to write code in one of two modes: the quick-and-dirty mode where you consistently don't check return values, or the built-to-last mode where you consistently do. If you start in the first mode and have to fix a bug, you often have to add error checking all up and down the call chain from where it occurs to where it'…

Your experience with languages with exceptions seem to come from people who misuse them. Randomly placing catch clauses around in the code is not good practice, even if perhaps a majority of all programmers in safe languages code that way. That causes latent bugs that are incredibly hard to debug.

The trick is to almost never ever catch exceptions. For example, in his post he describes a bug caused by accessing beyond allocated memory. That would in a safe language immediately have caused an ArrayIndexOutOfBoundsException (or equivalent) which the programmer would have fixed. In C, errors are often "silent" because you can't be bothered to check the return value of every call to printf. In a correctly coded program in a safe language errors are never ever silent.

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

#22
post #2

Adjusted for effort I don't know of any evidence that they are...

This really does depend on how "reliable" is defined. At the code level, reliable is dependent on the actual programmer. This code must then be compiled/interpreted in order to to actually function. At this stage the programmer has lost control unless they are also in direct control of the interpreter/compiler - which is, of course, impractical and extremely unlikely.

Inevitably writing in high level languages sacrifices control for how the program looks at the machine level simply because you must depend on existing structures. The higher up you go, the less control you have of the final product. Writing in Python vs. C means that you have to think less about lower level issues and consequently are subject to problems that arise outside the scope of what you could have originally controlled - simply because you didn't have to think about a subclass of issues that you assumed were inherently solved for you.

So yes - if you take a Python program and rewrite it in C, you can get a more reliable program IF you properly solved the set of things that Python took care of for you in relation to your specific problem.

But this relies on the fact that you succeeded in rewriting what Python took care of for you. So we're back to where we started - it all depends on the programmer.

The article implies this in the final sentence:

All that said, I don't recommend using C unless much thought has been given to the decision - the resulting software might be reliable, but it will have taken a significant human effort to produce it.

And this basically negates that C is any more reliable than whatever other programming language. Despite the fact that I think a discussion of reliability of a language is effectively useless (at least the way I've framed it here, I'm open to other interpretations), I enjoyed the article - thanks for sharing!

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

#23

The author makes a good point about the discipline imposed by not having exceptions. Programmers tend to write code in one of two modes: the quick-and-dirty mode where you consistently don't check return values, or the built-to-last mode where you consistently do. If you start in the first mode and have to fix a bug, you often have to add error checking all up and down the call chain from where it occurs to where it'…

"Discipline" is indeed the right word.

I was taught C at Epitech. A single segfault, no matter insidious, was a valid reason to render a whole project NULL. We often had evaluations ran with LD_LIBRATY_PATH=malloc_that_fails.so or just piping /dev/urandom to stdin...

Needless to say, calling exit() when a call to malloc() failed wasn't an acceptable recover routine.

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

#24
post #5

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…

> E.g. Lisp, along with PG, is the reason why HN is good. Many of HN's features simply wouldn't be easily accomplished without it Could you expand/elaborate on this? I've never viewed HN as particularly complex, just tastefully designed with a good community.

I never read the Arc source but I bet what he means is how comments are laid out in memory which you can see is reflected with direct links:

https://news.ycombinator.com/item?id=6857138

I'm not sure why that would be impossible in a none-lisp, just less elegant.

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

#25
Also, compile-time checks and the tendency of lower-level languages to fail catastrophically rather than subtly or silently plays a part. The author also has a lot of experience to draw on, which might just make his work more solid and error free in the first place.

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

#26

The author makes a good point about the discipline imposed by not having exceptions. Programmers tend to write code in one of two modes: the quick-and-dirty mode where you consistently don't check return values, or the built-to-last mode where you consistently do. If you start in the first mode and have to fix a bug, you often have to add error checking all up and down the call chain from where it occurs to where it'…

"Discipline" is indeed the right word. I was taught C at Epitech. A single segfault, no matter insidious, was a valid reason to render a whole project NULL. We often had evaluations ran with LD_LIBRATY_PATH=malloc_that_fails.so or just piping /dev/urandom to stdin... Needless to say, calling exit() when a call to malloc() failed wasn't an acceptable recover routine.

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

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

#27

The author makes a good point about the discipline imposed by not having exceptions. Programmers tend to write code in one of two modes: the quick-and-dirty mode where you consistently don't check return values, or the built-to-last mode where you consistently do. If you start in the first mode and have to fix a bug, you often have to add error checking all up and down the call chain from where it occurs to where it'…

"Discipline" is indeed the right word. I was taught C at Epitech. A single segfault, no matter insidious, was a valid reason to render a whole project NULL. We often had evaluations ran with LD_LIBRATY_PATH=malloc_that_fails.so or just piping /dev/urandom to stdin... Needless to say, calling exit() when a call to malloc() failed wasn't an acceptable recover routine.

I suspect you mean LD_PRELOAD=whatever.so

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

#28
post #8

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…

Wait, HN is good? The community is interesting, but I've never been particularly impressed by the implementation. In particular, the "feature" where "More" links and such randomly expire after a while just screams "shoddy implementation" to me.

The thing is, the "more" links are specific to each user and generated page. They're not just "page 3 at the time you click on the link", but the actual next 30 links following the 30 it's previously shown you. As a result, it needs to store state for each of these links it's created (IIRC, the fnid is a reference to the closure containing that state). For obvious memory management purposes, these need to be expired after some time.

I agree that it's an odd implementation choice though. I guess it made sense when HN was smaller and it could grant more ressources to each user. Nowadays, Reddit's simpler system (with risks of duplicates or missing rising links as you go deeper) would probably make more sense.

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

#29
post #8

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…

Wait, HN is good? The community is interesting, but I've never been particularly impressed by the implementation. In particular, the "feature" where "More" links and such randomly expire after a while just screams "shoddy implementation" to me.

Yeah, I really can't believe that hasn't been fixed by now.

Not only that, but it's impossible to follow discussions here. You have to go through your comment history to find threads you reply to.

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

#30

"[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.
Post reply on HN