Live data from Hacker News

How can C Programs be so Reliable? (2008)

tratt.net

201–210 of 230 posts

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

#201
post #196
post #189

Earlier quoted context omitted.

What you've described looks just as messy to my eyes, and I've seen all different ways to do this. You can nest under if(thing!=NULL) but then you end up with indentation creep. You can use the goto pattern if you like but some folks will tell you that goto's are never, ever to be used. Or you can do what's done above. When it comes down to it the logic is basically identical and it's just down to code formatting.

The logic may be identical but the scope for programmer error is not. Consider the possible mistakes someone can write by doing it each different way.

I've seen errors in all the ways considered here.

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

#202
post #63

Popular C software is so reliable because of enormous amount of effort spent developing, testing, and polishing it over many years - not because error handling in C is superior to that in higher-level languages. If your python script sticks around for 30 years constantly being used by millions of people - I bet it will be rock solid as well. All other things [1] being equal [2], a program written in a higher-level la…

I disagree with 4. How else would you recommend structuring this:

  try{
    lst.Where(i => i.ID == itm.ID).First().Amount += itm.Amount
  } catch (InvalidOperationException) {
    lst.Add(itm);
  }
I could check if the list contains it first, but this is more convenient. This is just one small example of a lot of cases where I've used typed exceptions successfully - in some cases I have multiple catches that do different things, eg catch(InvalidOperationException){...}catch(ArgumentNullException){...} this saves a lot of lines of pre-checking and has a clear control flow.

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

#203

Earlier quoted context omitted.

Exceptions are kind of like gotos, but worse, because the jump target is decided at runtime based on the state of the call stack and therefore cannot be determined just by looking at the code. So they're more like comefroms [0] than gotos. [0] http://en.wikipedia.org/wiki/COMEFROM

Right, which is why they are reserved for situations where you are not trying to "jump somewhere", but just want to give up and crash, because further execution in the current context has failed. If some external calling context really does not want to crash, the implementation of failing function doesn't and shouldn't care.

[deleted]

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

#204
post #67

Earlier quoted context omitted.

Embedded systems like this do not use dynamic memory allocation.

I knew that people would nit-pick on this and not address the actual issue. Next time, I should try harder to come up with a better example. My point is: sometimes it is worth trying to recover when malloc() fails.

I wasn't trying to nitpick. Correcting the example, and yes recovering from a malloc failure _could_ be a worthy goal, but on Linux by the time your app is getting signaled about malloc failures the OOM killer is already playing little bunny foo foo with ur processes.

If your app can operate under different allocation regimes then there should be side channels for dynamically adjusting the memory usage at runtime. On Linux, failed malloc is not that signal and since _so many_ libraries and language runtime semantics allocate memory, making sure you allocate no memory in your bad-malloc path is very difficult.

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

#205

Earlier quoted context omitted.

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

Certainly I have (the former, not the latter). You won't be surprised when I tell you that it wasn't a horrible tragedy and that I didn't die on the spot because of this, or accidentally purchase a handgun instead of a watermelon. In fact, it was such a minor event that I hadn't taken the time to make plans ahead of time for such an eventuality. Likewise, the first time I used pointers, nobody told me ahead of time that it was even possible to have a pointer that pointed to nothing. Understanding this, and (more crucially) learning exactly how to know when a pointer was and was not valid, was what got me my first merit badge in C. Everything before that was just Pascal with less formality.

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

#206

Earlier quoted context omitted.

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

It's not really a problem with the analogy; I'm just saying that a good analogy is no cure for a lack of experience. My first non-toy C program was a disaster because I knew what a pointer was but I didn't yet understand how to manage them.

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

#207
post #105
post #93

Earlier quoted context omitted.

Yes! Most software I've seen can be dramatically improved by removing exception handlers. (And then fixing the underlying problems). On the server side I prefer one exception handler which is the OS, it will kill your process, release and free all memory, file handlers, etc. Then I wrap it in a bash script / other monitoring tool, and have it immediately restart whenever it fails. As for the server itself I'll also a…

Are the servers you're building serving concurrent clients? An exception could take out multiple in-flight requests. (not against your idea, just curious how you handle it)

It's more of a question of what the semantics of failed requests are than concurrent clients.

The key is to segment your system so processing is orthogonal to the implementation details of the networking protocol on a given system. Just because on a particular OS when a process closes the TCP/IP connections are dropped does not mean that every time your process crashes that client connections are dropped.

In the case of a webserver you can use something like mongrel2 / nginx that maps physical connections to backend processes so that a process restart doesn't mean a dropped connection, or failed request.

Forcing your machines to reboot early and often makes you think about and deal with these problems rather than simply delaying them until one of your nodes dies and takes out a bunch of client connections anyway.

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

#208
post #187

Earlier quoted context omitted.

Not typically: using forking daemons does not mean that you can't also use threads. The ideal model probably uses both - so they can be stuck to a processor, but still use threads per request. It's nice to have a library to abstract the implementation details away for you, but not necessary.

Right, but doesn't the error handling approach you describe mean allowing a whole process to fail whenever an error condition occurs, which would cause any requests that were being handled by other threads of that process to fail even though they were perfectly valid?

Can you really tell me that you know after an exception that the other threads are really in a well-defined state let alone 'perfectly valid'?

Look at something like ZeroMQ that is being rewritten specifically to avoid the non-determinism inherent in throwing an exception.

Once you're using threads it's pretty much anyone's guess as to what state the system is in at any point, add exceptions and it just gets worse.

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

#209
post #169

Earlier quoted context omitted.

One advantage of forking servers; kill and reboot the parent, and you don't loose in-flight connections. That said, I do this as well, even the best behaved daemon can get... funky... after a few months. Planned outages for a daemon restart are ok in my experience, particularly if you can fail over to other nodes as part of a rolling restart. Of course, this refers to planned restarts, though forking servers helps wi…

Don't you find performance suffers? AIUI this approach means you can only handle as many concurrent requests as you have processes, and the OS scheduler has less information to work with than if you were using threads.

Why do you need to handle requests concurrently when something like the disruptor pattern can handle 6 million/sec on a single core.

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

#210

Earlier quoted context omitted.

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

It's not really a problem with the analogy; I'm just saying that a good analogy is no cure for a lack of experience. My first non-toy C program was a disaster because I knew what a pointer was but I didn't yet understand how to manage them.

Oh, for sure it's no cure for a lack of experience. My contention was solely with the statement that there is no real-world analogy. There is one; it's useful; it doesn't accomplish everything because it's just an analogy.
Post reply on HN