Live data from Hacker News

How can C Programs be so Reliable? (2008)

tratt.net

31–40 of 97 posts

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

#31

Is the mindset of exception handling so different than robust C code? In both cases you have to choose to diligently handle errors and check the code/docs for all cases that can come up. Writing code with the occasional try/catch block isn't too different from writing C and not checking error conditions

> Writing code with the occasional try/catch block isn't too different from writing C and not checking error conditions I think a critical difference is that in C the program is more liable to simply crash if errors aren't correctly handled, whereas in Java/Python/etc the program can just log a stack trace and keep on truckin', even if the bug is actually quite severe. In some cases a crash is preferable - e.g. if so…

So it is worse, therefore it is better?

Exceptions are exceptionally good at error handling - they always do the correct default (bubbling up if not handled, bringing a stacktrace with them, and by default they auto-unwrap the correct return value, not making the actual business logic hard to decipher), plus they make error handling possible on as wide scope as needed (try block vs a single return value).

I absolutely fail to see how a “random” C program would fair better, I’m sure the errno state is not checked at every line, as it is a trivial human error to leave that out. You can’t forget exceptions, which is how it should be!

If anything, that java/python text editor will catch every exception at the top level, save the file and exit with an error message and it will be the C program that either randomly crashes, or ignores some exceptional state.

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

#32

Earlier quoted context omitted.

Rust is better for this since your program won’t even compile until you’ve handled those error states.

> Rust is better for this since your program won’t even compile until you’ve handled those error states. How is that better for developing a sense of paranoia around error states? "Throw it at the wall and see what sticks" does not exactly lead to "extreme paranoia managing errors".

You're placing a lot of trust in it not being undefined behavior.

Additionally, of course anything can be done with enough time and effort but the costs add up when you are doing things manually rather than letting the compiler handle it. Compiler has had many person-years of effort spent in ensuring the output is correct, can we do the same for all the code we write?

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

#33
post #24

Earlier quoted context omitted.

While I agree with last two paragraphs, C is not good even for that purpose because it doesn't give any tool to manage them. An effective C education should really be paired with various static analyses and formal verification strategies.

Well, there are such tools for C, but wouldn't using them be detrimental in this context? Think, like using a debugger vs. trying to wrap the execution in one's mind: I'not saying that one shouldn't use debuggers, but not using one has benefits, as a teaching device. Like running in a weight vest. Edit: ah, perhaps you meant, in addition to using raw C, one should also learn how to use such static analyzers & cie

> Edit: ah, perhaps you meant, in addition to using raw C, one should also learn how to use such static analyzers & cie

Exactly. Sorry for my unclear wording.

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

#34

I think every graduating student should work on a non-trivial application in plain C for a year before moving on to another language. It makes you exceptionally paranoid about failure states and practically requires a bit of thought and planning before attempting any non-trivial change. The mindset of "it's fine to ignore all error conditions and let the default exception handler print a stack trace to the user" resu…

While I agree with last two paragraphs, C is not good even for that purpose because it doesn't give any tool to manage them. An effective C education should really be paired with various static analyses and formal verification strategies.

> While I agree with last two paragraphs, C is not good even for that purpose because it doesn't give any tool to manage them.

The "purpose" here is to instill a sense of paranoia around error handling, so that the resulting program from the PoV of the user appears to handle whatever bizarre combination of inputs the user put in.

It's the difference between telling the user "Failed to open foo.txt (file not found). Do you want to create it?" and ending the program with a 100-line stack trace with "FileNotFoundException" buried somewhere in there.

As the article says, checked exceptions are not the solution here.

I've literally never seen, in a professional working environment, exception languages (Java, C#, Python, etc) actually check that the file they tried opening was actually opened, and if it wasn't, directing the user with a sensible message that allowed the user/operator to fix the problem.

In C, the very first time that you fail to check that `fopen` returned non-NULL, the program crashes. Then you check if it returned NULL, and need to put something in the handling code, so you look at what `errno` has, or convert `errno` to a string.

I will bet good money that you could grab the nearest C#/Java/Python/JS/etc engineer to you, ask them to find the most recent code they wrote that opened and read/wrote a file, and you'll find that there is literally no code to direct the user if the file-open failed. The default runtime handler steps in and vomits a stack trace onto the screen.

In C, you are forced to perform the NULL-check, or crash. Sure, many devs are simply going to have a no-op code-path for the error cases, doing `if ((inf = fopen(...)) != NULL) { DoSomethingWith(inf);}`, but proceeding on success is a code-smell and easy to visually spot as an error.

The exception languages make it virtually impossible to spot the code-smell of handled (or improperly handled) exceptions, and make it easy because the dev can just read the stack trace, create the file needed, and proceed with programming the rest of the app.

What a good program must do when a file open failure is encountered is direct the user in some way that they can fix the problem. For example "file doesn't exist. Create it [button], Choose a file [button]", or "Permission denied. Try running as a different user.", or "File is locked. Are you already running $PROGRAM?", or "$FOO is a directory. Specify a file.".

[EDIT: Yes, seeing a stack trace in a shipped product is one of my personal bugbears that I feel very strongly about. If it's a stack trace for an expected error (like failure to open/read/write a file) I absolutelydo get annoyed by this public display of laziness. And yes, this is one of those hills I'll die on before I leave it!]

Even the simplest c/line programs annoy me no end when the application simply dumps a stack trace to the screen. Sure, I can dig into it, but the average user is going to ask for help on stackoverflow, just to figure out what must be done to fix the error.

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

#35

Earlier quoted context omitted.

While I agree with last two paragraphs, C is not good even for that purpose because it doesn't give any tool to manage them. An effective C education should really be paired with various static analyses and formal verification strategies.

> While I agree with last two paragraphs, C is not good even for that purpose because it doesn't give any tool to manage them. That is the reason it should be used as a learning tool. So that you know the nitty gritty details without anyone "managing" it away from you.

Then learn an assembly language instead, because C also has a fair amount of bookkeeping hidden behind the scene.

C is typically described as a "low-level" programming language, where the "low-level" normally refers to the supposed distance from the language to the actual hardware. But as many incidents with UB demonstrate, this distance is still quite larger than expected. I think there is another sense of the word "low-level", which is the amount of abstractions that are either built into the language or allowed for users, and C doesn't have a lot of them.

Combined together they represent related but distinct axes of controllability, and C only achieves a modest level of controllability in one axis but not in another. The ideal language with controllability in comparison should minimize the distance to the machine and maximize an amount of abstraction to control anything below the language instead.

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

#36
I think the reliability gap is in statically typed, compiled languages versus dynamically typed languages. I think C++ is a good combination of both worlds. You don't have to type quite as much for error checking an manual management and you get a correctly typed program by default.

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

#37

Earlier quoted context omitted.

While I agree with last two paragraphs, C is not good even for that purpose because it doesn't give any tool to manage them. An effective C education should really be paired with various static analyses and formal verification strategies.

> While I agree with last two paragraphs, C is not good even for that purpose because it doesn't give any tool to manage them. The "purpose" here is to instill a sense of paranoia around error handling, so that the resulting program from the PoV of the user appears to handle whatever bizarre combination of inputs the user put in. It's the difference between telling the user "Failed to open foo.txt (file not found). D…

Eh Java/js or whatever developers working on user applications can be very user minded simply by the fact that they work on a lot of user facing applications. I’ll redirect the user if it makes sense to me as a product. I don’t buy it that C forcing you to do a handle the input is advantageous in this regard.

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

#38

Earlier quoted context omitted.

While I agree with last two paragraphs, C is not good even for that purpose because it doesn't give any tool to manage them. An effective C education should really be paired with various static analyses and formal verification strategies.

> While I agree with last two paragraphs, C is not good even for that purpose because it doesn't give any tool to manage them. The "purpose" here is to instill a sense of paranoia around error handling, so that the resulting program from the PoV of the user appears to handle whatever bizarre combination of inputs the user put in. It's the difference between telling the user "Failed to open foo.txt (file not found). D…

> As the article says, checked exceptions are not the solution here.

Java had a very bad model of checked exceptions (the OP was written in 2008). A correct way is to make it a part of the type system, though it doesn't have to be a sum type like Rust, and make any error-related code path as convenient as possible to use.

> In C, you are forced to perform the NULL-check, or crash.

You don't necessarily crash if you failed to perform a NULL check! That's literally the single biggest problem with C's undefined behaviors. C looks like forcing checks only because most programmers do understand crashes are bad, so they do prepare for trivial or demonstrated crashes. But that's not guaranteed, and they can't easily prepare for non-crash failures without additional tools.

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

#39

Earlier quoted context omitted.

Rust is better for this since your program won’t even compile until you’ve handled those error states.

> Rust is better for this since your program won’t even compile until you’ve handled those error states. How is that better for developing a sense of paranoia around error states? "Throw it at the wall and see what sticks" does not exactly lead to "extreme paranoia managing errors".

This raises the question of whether that extreme paranoia prevents critical errors in code. The fact that so many of the issues still persist suggests it does not.

You can tell people to be careful drivers all you want, but what really saves lives is airbags, crumple zones, and seatbelts.

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

#40

The author started by seriously admitting the drawbacks of C. Then, somehow, he says thanks to those flaws he has to pay higher attention when building software in C, he created very reliable tools. That's something I can understand because when I wanted to buy a motorbike I was advised to ride a bicycle first since it's more difficult to control. Except that the White House called recently for companies to not use n…

I built a house by only using a broken hammer, that made the house better because I needed to spend more time to handle the broken hammer correctly.
Post reply on HN