12 ms·
How can C Programs be so Reliable? (2008)
- nighthawk454 3y agoIs 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
- nicklecompte 3y ago> 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 something goes wrong in a text editor while saving data, it's a lot better for the user if the program crashes versus the alternative where the editor runs as normal but saving doesn't work. Crashes in C also bring more urgency for developers to actually fix the bug compared to a try/catch in Python that simply buries it "until I get a chance to debug it properly." (But crashing also leads to a lot of frustration when the error wasn't that important and the C program should have just kept going.)
- kaba0 3y agoSo 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.
- tored 3y agoMany years ago I started to dislike exception handling, probably because working in large software projects with many exceptions floating around. Then a few years ago I started to write code in a primitive language without exception handling. I miss exceptions now.
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- nicklecompte 3y ago> Converse curiously; don't cross-examine. Edit out swipes. > Please respond to the strongest plausible interpretation of what someone says, not a weaker one that's easier to criticize. > Eschew flamebait. Avoid generic tangents. In particular you seem to be responding to a strawman, since nowhere did I say C error handling was better than structured exceptions. The parent asked what was functionally different between laziness around checking error codes versus laziness around try/catching.
- kaba0 3y agoYou wrote: > in C the program is more liable to simply crash I simply disagree with this statement, as silent failure is also very common in case of C, which is probably the worst option. (Especially that it may cause memory safety issues, that may not even materialize until much later). No need to take my comment that seriously though, I had no bad intention whatsoever.
- acuozzo 3y ago> I’m sure the errno state is not checked at every line, as it is a trivial human error to leave that out While writing code it's trivial to ask yourself if the next statement will include a call to a function which is not defined within a compilation unit under your control. If it will, then you lookup documentation for that function to determine what it expects and how it can fail. Most of my functions which interact with such functions look like long sequences of this: /* close the file */ ret = -1; do { errno = 0; ret = close(fildes); } while (0 != ret && EINTR == errno); if (0 != ret) { perror("Error"); goto off_ramp; } I've caused plenty of bugs in my career, but I can say with confidence that 0 of them had to do with ignoring/skipping proper error handling. You have to do so intentionally.
- kazinator 3y agoIf you work with enough C code, you will come across exception handling. I made an exception handling library long ago. It lives mainly in Wireshark.
- deleted 3y ago[deleted]
- rramadass 3y agoThough not specific to C language, C.A.R Hoare's Retrospective: An Axiomatic Basis for Computer Programming provides insight on why Software is so reliable in spite of a lack of application of formal verification methods. Retrospective: https://cacm.acm.org/opinion/retrospective-an-axiomatic-basis-for-computer-programming/ https://cacm.acm.org/opinion/retrospective-an-axiomatic-basi... Here is a pdf of the retrospective along with the original paper : https://harrymoreno.com/assets/greatPapersInCompSci/2.2_-_An_Axiomatic_Basis_for_Computer_Programming_-_C._A._R._Hoare.pdf https://harrymoreno.com/assets/greatPapersInCompSci/2.2_-_An...
- Jtsummers 3y agoHere is another paper of his related to this: How Did Software Get So Reliable Without Proof? C.A.R. Hoare 1996 (?) http://users.csc.calpoly.edu/~gfisher/classes/509/handouts/hoare-without-proof.pdf http://users.csc.calpoly.edu/~gfisher/classes/509/handouts/h...
- deleted 3y ago[deleted]
- AtlasBarfed 3y ago1) were C programmers "better"? In sum total, pretty much. 2) C programs, at least the ones we use now, are a product of a lot of use and debugging 3) It didn't take too many debugging sessions as a C programmer to learn to program a bit more carefully. 4) and the more it gets used, the more error codes it encounters, and the more robust the handling gets. I think a dirty secret of software engineering isn't that the most complicated/heavily used code gets the most and most useful comments, it's that it also get the most error handling/detection code, and for the vast majority of non-core loop code: error handling ..isn't.
- wiseowise 3y ago> were C programmers "better"? In sum total, pretty much No. Original programmers that just happened to use C were better, not the other way around.
- bdjsiqoocwk 3y agoI disagree. The early adopters are usually exceptional. When adoption grows the average level decreases. This is a well known phenomenon which is larger than just programmers. It was even on HN recently, as applied to IQs in high schools over time: as more kids reach high school, the average decreases. So yes. C programmers were better.
- wiseowise 3y agoYou’re literally proving my point and then summarizing with different conclusion. They were exceptional because they were exceptional, not because they were C developers.
- lelanthran 3y agoI 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" results in software that is annoying to the user.
- lifthrasiir 3y agoWhile 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.
- mbivert 3y agoWell, 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
- lifthrasiir 3y ago> 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.
- quelsolaar 3y agoAs the author notes, to know what C code does you need to run it. A good debgger is a C programmers best friend.
- mbivert 3y ago
- begueradj 3y agoThe 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 non memory safe languages such as C to build software.
- mgaunard 3y agoThat's not what the white house said and they're not an authority in software engineering anyway. Just sensationalist journalism.
- begueradj 3y agoIs Stack Overflow also sensationalist journalism ? https://stackoverflow.blog/2024/03/04/in-rust-we-trust-white-house-office-urges-memory-safety/ https://stackoverflow.blog/2024/03/04/in-rust-we-trust-white... In 6 hours, I will share the link to the official and related White House PDF document.
- topspin 3y agoThis is what the White House said: https://www.whitehouse.gov/wp-content/uploads/2024/02/Final-ONCD-Technical-Report.pdf https://www.whitehouse.gov/wp-content/uploads/2024/02/Final-... Interpreting this as "stop using C/C++" isn't much of a stretch. Yes, it is not a demand. Anticipating such a demand isn't a bad bet, however. Who is an authority, anyhow? The White House is citing NIST, DHS, Microsoft, Cambridge DSCT, Google and others. Whom do you offer? I don't like this myself. We're rapidly building tools that could conceivably solve memory safety in C/C++ code bases. I don't want C pilloried by Authority and its group thinking ways.
- bdw5204 3y agoAt most, the White House's opinion on C/C++ will impact government contractors and people who care about the White House's opinion on matters it isn't qualified to speak about. I'd only be worried if I were in the business of selling software written in C/C++ to the government but a few campaign donations to politicians would probably get that fixed.
- kazinator 3y agoReliable is not the same as portable, which is not the same as well-defined according to the language spec. The consequences of doing something incorrect or nonportable is sometimes that the expected behavior occurs. This can be validated by testing on the couple of platforms (or just one) that the program supports, and kept working. Another thing we need to consider is that reliable is not the same thing as robust, let alone secure. A program that appears reliable to a user who uses it "as directed", giving it the expected kinds of inputs, will not necessarily appear reliable to a tester looking for ways to break it, or to a cracker trying to exploit it. A truly reliable program not only handles all its functional use cases according to its requirements, but is impervious to deliberate misuse, no matter how clever. Security flaws are found in reliable, well-debugged programs used in production by millions.
- msla 3y ago> The consequences of doing something incorrect or nonportable is sometimes that the expected behavior occurs. This can be validated by testing on the couple of platforms (or just one) that the program supports, and kept working. A practical example of this is word size issues: A program that casts pointers to ints everywhere is perfectly reliable on 32-bit machines, but it will die horribly on any LP64 machine, which are most 64-bit machines. Related are endianness issues, which is why projects have tended to stop supporting big-endian systems: They're just too rare to scrounge up anymore, and unless you're actively testing on them, bugs can slip in which will not be caught on little-endian hardware. Similarly, OS developers stop supporting architectures when they can no longer find working examples of them. This is because emulators have bugs, and without a source of truth (working hardware) it's very hard to determine if a bug you just found is in the OS or the emulator; add unreliable hardware to that and things just get worse. Bob Supnik (former DEC VP, creator of SimH) has a PDF: http://simh.trailing-edge.com/docs/bugfeature.pdf http://simh.trailing-edge.com/docs/bugfeature.pdf
- norir 3y agoC is horrible for exploratory programming but is acceptable if you already know how to solve the problem. If one uses enums for errors, then the compiler can check for you that all edge cases are handled. You can log an error and exit(1) for unhandled cases during development which makes it feasible to turn on -Werror but not have to implement every edge case up front. You can do the same thing with tagged unions to implement a poor man's sum types. It is significantly more verbose than in a language that has syntactic support for this, but you get similar compile time safety guarantees.
- whiterknight 3y ago> C is horrible for exploratory programming Completely disagree. The lack of screwing around selecting abstractions forces you to make something productive right away and not stress about refactor.
- theyinwhy 3y agoIsn't "forced to make sth productive right away" the opposite of "exploratory programming"?
- GuestHNUser 3y agoNo, I think exploratory programming is exactly that. Solutions to a problem is the very thing to be explored.
- tored 3y agoWho is stressing you to refactor when doing exploratory programming? Yourself? OOP languages? Society?
- deleted 3y ago[deleted]
- insomagent 3y agoIf you're talking about something like a web server, then sure. If you're talking about kernel hacking, then I completely disagree.
- cjfd 3y agoI 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.
- deleted 3y ago[deleted]
- xigoi 3y agoStatic typing is useless without strict typing. Knowing the type of everything won’t save you if you can multiply a pointer by an integer and use the result as a file handle.
- fanf2 3y agoFortunately even C and C++ compilers will complain if you try to do that.
- lelanthran 3y ago> Static typing is useless without strict typing. Knowing the type of everything won’t save you if you can multiply a pointer by an integer and use the result as a file handle. What language are you talking about? Go to godbolt and try that with any of the compilers there for C or C++.
- xigoi 3y agoCompiles with only a warning: #include <stdio.h> int main() { int x = 5; int y = &x; FILE *f = x * y; fputs("hello", f); }
- lelanthran 3y agoSo what are you complaining about? That the compiler told you "Don't do that" but you ignored it? I mean, you said: >> Knowing the type of everything won’t save you but the compiler is trying to save you! You have to actively work against it in order to hang yourself, and you blame the language?
- quelsolaar 3y agoC suffers from a terrible case of survivor bias. C is so effective for writing all of the most critical software, that almost all software people trust is written in C. Therefore almost all critical vulnerabilities are found in C code.
- tored 3y agoThis text doesn’t make much sense, on the one hand the author argues that software written in C is robust, on the other hand the author admits that he has unknown bugs lurking in his own project. One bug took several months to track down. This is cognitive dissonance at its finest.
- BobbyTables2 3y agoUntil one writes a nontrivial program that properly handles -EINTR errors on every possible point, I don’t anyone should brag about their error handing prowess. It is also hard to handle errors more meaningfully than instantly terminating the process at the first whif of something going sideways. And once you do write such a thing, try making automated tests to exercise it!! How many programs actually check the return value of close() ? Sure, this sounds a bit Linux/POSIX specific. There are only a few billion devises running such code, perhaps I’m overreacting…